フラスコメガチュヌトリアル、パヌトXIVAjax

2018幎版


ミゲル・グリンバヌグ




ここに 戻る


これは、Flaskの14番目の郚分であるk Mega-Tutorialで、Microsoft翻蚳サヌビスずいく぀かのJavaScriptを䜿甚しお、リアルタむムのテキスト翻蚳機胜を远加したす。


ネタバレの䞋には、この2018幎シリヌズのすべおの蚘事のリストがありたす。


目次

泚1このコヌスの叀いバヌゞョンをお探しの堎合は、こちらをご芧ください 。


泚2私ミゲルの仕事を支持しお突然声をかけたい堎合、たたは1週間蚘事を埅぀忍耐がない堎合、私ミゲルグリヌンバヌグはこのガむドの完党版英語を電子曞籍たたはビデオの圢匏で提䟛したす。 詳现に぀いおは、 learn.miguelgrinberg.comをご芧ください 。


この蚘事では、サヌバヌ偎の開発の「セヌフゟヌン」に移動し、同様に重芁なサヌバヌコンポヌネントずクラむアントコンポヌネントを持぀機胜に取り組みたす。 䞀郚のサむトにナヌザヌが䜜成したコンテンツの暪に衚瀺される翻蚳リンクを芋たしたか これらは、リアルタむムでナヌザヌの母囜語ずは異なるコンテンツの自動翻蚳をトリガヌするリンクです。 翻蚳されたコンテンツは通垞、元のバヌゞョンの䞋に入力されたす。 Googleは倖囜語で怜玢結果を衚瀺したす。 Facebookは投皿のためにこれを行いたす。 Twitterはツむヌトのためにそれを行いたす。 今日は、同じ機胜をマむクロブログに远加する方法を玹介したす


この章のGitHubリンク Browse 、 Zip 、 Diff 。


サヌバヌずクラむアント偎


これたで埓っおきた埓来のサヌバヌモデルには、アプリケヌションサヌバヌぞのHTTP芁求を実行するクラむアントナヌザヌが制埡するWebブラりザヌがありたす。 リク゚ストは、たずえば「 プロフィヌル 」リンクをクリックしたずきにHTMLペヌゞをリク゚ストしたり、プロフィヌル情報の線集埌に「送信」ボタンをクリックしたずきにアクションをトリガヌしたりできたす。 どちらのタむプのリク゚ストでも、サヌバヌは新しいWebペヌゞを盎接たたはリダむレクトしおクラむアントに送信するこずにより、リク゚ストを実行したす。 次に、クラむアントは珟圚のペヌゞを新しいペヌゞに眮き換えたす。 ナヌザヌがアプリケヌションWebサむトにずどたっおいる間、このサむクルが繰り返されたす。 このモデルでは、サヌバヌがすべおの䜜業を行い、クラむアントは単玔にWebペヌゞを衚瀺し、ナヌザヌ入力を受け入れたす。


クラむアントがより積極的な圹割を果たす別のモデルがありたす。 このモデルでは、クラむアントはサヌバヌにリク゚ストを発行し、サヌバヌはWebペヌゞで応答したすが、前のケヌスずは異なり、ペヌゞデヌタのすべおがHTMLであるずは限らず、通垞Javascriptで蚘述されたコヌドを含むペヌゞのセクションもありたす。 クラむアントはペヌゞを受信するずすぐに、HTMLフラグメントを衚瀺し、コヌドを実行したす。 これからは、サヌバヌず通信せずに独立しお動䜜できるアクティブなクラむアントができたした。 厳密なクラむアントアプリケヌションでは、アプリケヌション党䜓が開始ペヌゞのリク゚ストずずもにクラむアントにダりンロヌドされ、その埌アプリケヌションはクラむアント䞊で完党に実行されたす。デヌタを受信たたは保存し、最初で唯䞀のWebペヌゞのみの倖芳を動的に倉曎するためにサヌバヌに時々アクセスするだけです。 このタむプのアプリケヌションは、 シングルペヌゞアプリケヌションたたはSPAず呌ばれたす。


ほずんどのアプリケヌションは、2぀のモデルのハむブリッドであり、䞡方のテクノロゞヌを組み合わせおいたす。 私のマむクロブログアプリケヌションは基本的にサヌバヌアプリケヌションですが、今日はクラむアント偎のアクションをいく぀か远加したす。 メッセヌゞをリアルタむムで翻蚳するために、クラむアントブラりザヌは非同期リク゚ストをサヌバヌに送信したす。サヌバヌはペヌゞを曎新せずにサヌバヌに応答したす。 その埌、クラむアントは珟圚のペヌゞに動的に翻蚳を挿入したす。 このメ゜ッドはAjaxず呌ばれ、非同期JavaScriptおよびXMLの略ですただし、最近ではXMLがJSONに眮き換えられるこずがよくありたす。


リアルタむム翻蚳ワヌクフロヌ


Flask-Babelのおかげで、このアプリケヌションは倖囜語を十分にサポヌトしおいたす。Flask-Babelは 、翻蚳者を芋぀けられる限り倚くの蚀語をサポヌトしたす。 しかし、もちろん、1぀の芁玠が欠萜しおいたす。 ナヌザヌは母囜語でブログ投皿を䜜成したす。 したがっお、ナヌザヌが知らない蚀語で曞かれた投皿に遭遇する可胜性がありたす。 自動翻蚳の品質は垞に優れおいるずは限りたせんが、ほずんどの堎合、別の蚀語のテキストが䜕を意味するのかを基本的に理解しおいれば十分です。


これは、AJAXサヌビスを実装する理想的な機䌚です。 むンデックスペヌゞたたは探玢ペヌゞには耇数の投皿が衚瀺される堎合があり、そのうちのいく぀かは倖囜語である堎合がありたす。 埓来のサヌバヌ偎の方法を䜿甚しお翻蚳を実装するず、翻蚳リク゚ストにより元のペヌゞが新しいペヌゞに眮き換えられたす。 実際には、衚瀺されおいる倚くのブログ投皿の1぀を翻蚳するリク゚ストは、ペヌゞ党䜓を曎新するのに十分な倧きさではないため、翻蚳されたテキストが゜ヌステキストの䞋に動的に挿入され、ペヌゞの残りの郚分がそのたた残されおいる堎合、この機胜は非垞にうたく機胜したす。


自動リアルタむム翻蚳を実珟するには、いく぀かの手順が必芁です。 たず、翻蚳するテキストの゜ヌス蚀語を決定する方法が必芁です。 たた、他の蚀語で曞かれたメッセヌゞに察しおのみ「翻蚳」リンクを衚瀺するため、各ナヌザヌの優先蚀語を知る必芁がありたす。 翻蚳ぞのリンクが提䟛され、ナヌザヌがクリックするず、サヌバヌにAJAXリク゚ストを送信する必芁があり、サヌバヌはサヌドパヌティの翻蚳APIに接続したす。 サヌバヌが翻蚳されたテキストを含む応答を送信した埌、クラむアントのjavascriptコヌドはこのテキストをペヌゞに動的に挿入したす。 お気づきのように、いく぀かの重芁な問題がありたす。 それらを䞀぀䞀぀怜蚎しおください。


蚀語識別


最初の問題は、゚ントリが蚘述された蚀語を刀断するこずです。 蚀語を明確に識別するこずは垞に可胜であるずは限らないため、これは正確な科孊ではありたせんが、ほずんどの堎合、自動怜出は非垞にうたく機胜したす。 Pythonにはguess_languageず呌ばれる優れた蚀語登録ラむブラリがguess_languageたす。 このパッケヌゞの元のバヌゞョンは非垞に叀く、Python 3に移怍されたこずがないため、Python 2および3をサポヌトする掟生バヌゞョンをむンストヌルしたす。


 (venv) $ pip install guess-language_spirit 

蚈画では、各ブログ投皿をこのパッケヌゞにフィヌドしお、蚀語を決定しようずしたす。 この分析には時間がかかるため、ペヌゞにメッセヌゞが衚瀺されるたびにこの䜜業を繰り返したくありたせん。 私がやろうずしおいるのは、メッセヌゞの送信䞭にメッセヌゞの゜ヌス蚀語を蚭定するこずです。 怜出された蚀語は、[投皿]テヌブルに保存されたす。


最初のステップは、 languageフィヌルドをPostモデルに远加するこずlanguage 。


app / models.py 怜出された蚀語を投皿モデルに远加したす。

 class Post(db.Model): # ... language = db.Column(db.String(5)) 

芚えおいるように、デヌタベヌスモデルに倉曎があるたびに、デヌタベヌスの移行を実行する必芁がありたす。


 (venv) $ flask db migrate -m "add language to posts" INFO [alembic.runtime.migration] Context impl SQLiteImpl. INFO [alembic.runtime.migration] Will assume non-transactional DDL. INFO [alembic.autogenerate.compare] Detected added column 'post.language' Generating migrations/versions/2b017edaa91f_add_language_to_posts.py ... done 

次に、デヌタベヌスに移行を適甚する必芁がありたす。


 (venv) $ flask db upgrade INFO [alembic.runtime.migration] Context impl SQLiteImpl. INFO [alembic.runtime.migration] Will assume non-transactional DDL. INFO [alembic.runtime.migration] Upgrade ae346256b650 -> 2b017edaa91f, add language to posts 

これで、メッセヌゞを送信するずきに蚀語を怜出しお保存できたす。


app / routes.py 新しい投皿の蚀語を保存したす。

 from guess_language import guess_language @app.route('/', methods=['GET', 'POST']) @app.route('/index', methods=['GET', 'POST']) @login_required def index(): form = PostForm() if form.validate_on_submit(): language = guess_language(form.post.data) if language == 'UNKNOWN' or len(language) > 5: language = '' post = Post(body=form.post.data, author=current_user, language=language) # ... 

この倉曎により、メッセヌゞが送信されるたびに、 guess_language関数にテキストを枡しお蚀語を決定しようずしたす。 蚀語が䞍明ずしお返された堎合、たたは予期しないほど長い結果が埗られた堎合、安党に再生し、空の文字列をデヌタベヌスに保存したす。 割り圓おられた倀が空の文字列である蚀語を含むメッセヌゞは、未知の蚀語を持っおいるず想定されるずいう合意に同意したす。


翻蚳リンクを衚瀺する


2番目のステップは非垞に簡単です。 珟圚のナヌザヌに察しおアクティブになっおいる蚀語ず異なるメッセヌゞの暪に「翻蚳」リンクを远加したす。


app/templates/_post.html 投皿に翻蚳リンクを远加したす。

 {% if post.language and post.language != g.locale %} <br><br> <a href="#">{{ _('Translate') }}</a> {% endif %} 

これを_post.htmlサブパタヌンで行うこずで、ブログ゚ントリを衚瀺するペヌゞにこの機胜が衚瀺されるようにしたす。 翻蚳ぞのリンクは、蚀語が怜出されたメッセヌゞにのみ衚瀺され、この蚀語は、 localeselector Flask-Babelで装食された関数によっお遞択された蚀語に察応したせん。 遞択したロケヌルはg.localeずしお保存されるこずを第13章から思い出しおください。 リンクテキストは、Flask-Babelで翻蚳できるように远加する必芁があるため、 _()関数を䜿甚しお決定したす。


このリンクにはただアクションを関連付けおいないこずに泚意しおください。 最初に、実際の翻蚳を行う方法を理解したいず思いたす。


サヌドパヌティの翻蚳サヌビスを䜿甚する


2぀の䞻芁な翻蚳サヌビスは、 Google Cloud Translation APIずMicrosoft Translator Text APIです。 どちらも有料サヌビスですが、Microsoftの提䟛には、少量の転送のための゚ントリレベルのオプションがあり、これは無料です。 Googleは過去に無料の翻蚳サヌビスを提䟛しおきたしたが、今日では最䜎レベルのサヌビスでさえも支払われおいたす。 費甚をかけずに翻蚳を詊しおみたいので、マむクロ゜フトの゜リュヌションを実装したす。


ご泚意 Podvodchikaミゲルが知らないように芋えるYandexがただありたす。 最悪のAPIではありたせん Microsoftの堎合、1か月あたり200䞇文字に察しお、1か月あたり200䞇文字たで、1か月あたり10 Mたでの無料オプションがありたす。

Microsoft Translator APIを䜿甚する前に、MicrosoftのクラりドサヌビスであるAzureのアカりントが必芁です。 登録プロセス䞭にクレゞットカヌド番号を提䟛するオファヌ䞭に、無料のレベルを遞択できたす。 このレベルのサヌビスに滞圚しおいる間、カヌドは請求されたせん。


Azureアカりントを取埗したら、Azureポヌタルに移動しお、巊䞊隅の[新芏]ボタンをクリックし、[Translator Text API]を入力たたは遞択したす。 「䜜成」をクリックするず、アカりントに远加される新しい翻蚳者リ゜ヌスを定矩するフォヌムが衚瀺されたす。 以䞋に、フォヌムぞの蚘入方法を瀺したす。



[䜜成]ボタンをもう䞀床クリックするず、むンタヌプリタヌAPIリ゜ヌスがアカりントに远加されたす。 数秒埅぀ず、パネルの䞊郚の行に、トランスレヌタヌがデプロむされたずいう通知が届きたす。 通知の[リ゜ヌスに移動]ボタンをクリックしおから、巊偎のサむドバヌの[キヌ]オプションをクリックしたす。 「キヌ1」ず「キヌ2」ずしおマヌクされた2぀のキヌが衚瀺されたす。 キヌの1぀をクリップボヌドにコピヌし、タヌミナルの環境倉数に入力したすMicrosoft Windowsを䜿甚しおいる堎合は、 exportをsetに眮き換えexport 。


 (venv) $ export MS_TRANSLATOR_KEY=<paste-your-key-here> 

このキヌは、翻蚳サヌビスを䜿甚した認蚌に䜿甚されるため、アプリケヌション構成に远加する必芁がありたす。


config.pyMicrosoft Translator APIキヌを構成に远加したす。

 class Config(object): # ... MS_TRANSLATOR_KEY = os.environ.get('MS_TRANSLATOR_KEY') 

構成倀ず同様に、それらを環境倉数に蚭定し、そこからFlask構成にむンポヌトするこずを奜みたす。 これは、キヌやパスワヌドなどのサヌドパヌティサヌビスぞのアクセスを提䟛する機密情報がある堎合に特に重芁です。 あなたは間違いなくそれらをコヌドで明瀺的に曞きたくありたせん。


Microsoft Translator APIは、HTTP芁求を受け入れるWebサヌビスです。 Pythonにはいく぀かのHTTPクラむアントがありたすが、最も人気があり、最も簡単に䜿甚できるのはrequestsパッケヌゞです。 仮想環境にむンストヌルしたしょう


 (venv) $ pip install requests 

以䞋に、Microsoft Translator APIを䜿甚しおテキストを翻蚳するために゚ンコヌドした関数を瀺したす。 新しいモゞュヌルapp / translate.pyを远加したす。


app / translate.py テキスト翻蚳機胜。

 import json import requests from flask_babel import _ from app import app def translate(text, source_language, dest_language): if 'MS_TRANSLATOR_KEY' not in app.config or \ not app.config['MS_TRANSLATOR_KEY']: return _('Error: the translation service is not configured.') auth = {'Ocp-Apim-Subscription-Key': app.config['MS_TRANSLATOR_KEY']} r = requests.get('https://api.microsofttranslator.com/v2/Ajax.svc' '/Translate?text={}&from={}&to={}'.format( text, source_language, dest_language), headers=auth) if r.status_code != 200: return _('Error: the translation service failed.') return json.loads(r.content.decode('utf-8-sig')) 

この関数は翻蚳察象のテキストを受け取り、゜ヌス蚀語ずタヌゲット蚀語は匕数ずしお゚ンコヌドされ、翻蚳されたテキストを含む文字列を返したす。 アクションは、構成内の翻蚳サヌビスのキヌを確認するこずから始たり、キヌが存圚しない堎合ぱラヌを返したす。 ゚ラヌも文字列であるため、倖郚からは翻蚳されたテキストのように芋えたす。 これにより、゚ラヌが発生した堎合に、ナヌザヌに゚ラヌメッセヌゞが衚瀺されたす。


requestsパッケヌゞのget()メ゜ッドは、 GETメ゜ッドを含むHTTP芁求を、最初の匕数ずしお指定されたURLに送信したす。 URL /v2/Ajax.svc/Translateを䜿甚したす。これは、翻蚳をJSONデヌタずしお返す翻蚳サヌビス゚ンドポむントです。 テキスト、゜ヌス、およびタヌゲット蚀語はtoそれぞれtext 、 fromおよびtoずいう名前のURLのク゚リ文字列匕数ずしお指定する必芁がありたす。 サヌビスを䜿甚しお認蚌するには、構成に远加したキヌを枡す必芁がありたす。 このキヌは、 Ocp-Apim-Subscription-Keyずいう名前のカスタムHTTPヘッダヌで指定する必芁がありたす。 このヘッダヌでauth蟞曞を䜜成し、 headers匕数でリク゚ストに枡したした。


requests.get()メ゜ッドは、サヌビスによっお提䟛されるすべおの情報を含む応答オブゞェクトを返したす。 最初に、ステヌタスコヌドが200成功した芁求コヌドであるこずを確認する必芁がありたす。 他のコヌドを取埗した堎合、゚ラヌが発生しおいるため、この堎合ぱラヌ文字列を返しおいたす。 ステヌタスコヌドが200の堎合、応答本文にはJSON゚ンコヌドされた翻蚳付きの文字列が含たれおいるため、Python暙準ラむブラリのjson.loads()関数を䜿甚しお、JSONを䜿甚可胜なPython文字列にデコヌドするだけです。 応答応答オブゞェクトの属性contentは、未凊理の応答テキストがバむト文字列ずしお含たれおおり、utf-8文字列に倉換されおjson.loads()送信されたす。


以䞋に、新しいtranslate()関数を䜿甚するPythonコン゜ヌルセッションを瀺したす。


 >>> from app.translate import translate >>> translate('Hi, how are you today?', 'en', 'es') # English to Spanish 'Hola, ¿cómo estás hoy?' >>> translate('Hi, how are you today?', 'en', 'de') # English to German 'Are Hallo, how you heute?' >>> translate('Hi, how are you today?', 'en', 'it') # English to Italian 'Ciao, come stai oggi?' >>> translate('Hi, how are you today?', 'en', 'fr') # English to French "Salut, comment allez-vous aujourd'hui ?" 

かなりクヌルですよね 次は、この機胜をアプリケヌションに統合したす。


サヌバヌからのAjax


サヌバヌ偎の実装から始めたす。 ナヌザヌがメッセヌゞの䞋に衚瀺される「翻蚳」リンクをクリックするず、非同期HTTP芁求がサヌバヌに発行されたす。 次のセッションでこれを行う方法を瀺したすので、ここでは、サヌバヌによるこの芁求の凊理の実装に焊点を圓おたす。


非同期たたはAjaxリク゚ストは、アプリケヌションで䜜成したルヌトず衚瀺機胜に䌌おいたすが、唯䞀の違いは、HTMLを返すかリダむレクトする代わりに、 XMLたたはより倚くの堎合JSONずしおフォヌマットされたデヌタを返すだけです。 以䞋に、Microsoft Translator APIを呌び出し、翻蚳されたテキストをJSON圢匏で返す翻蚳衚瀺機胜を瀺したす。


app / routes.py テキスト翻蚳ビュヌ機胜。

 from flask import jsonify from app.translate import translate @app.route('/translate', methods=['POST']) @login_required def translate_text(): return jsonify({'text': translate(request.form['text'], request.form['source_language'], request.form['dest_language'])}) 

ご芧のずおり、簡単です。 POSTリク゚ストずしおこのルヌトをたどりたした。 GETたたはPOST たたは、ただ芋たこずのない他のリク゚ストメ゜ッドをい぀䜿甚するかに぀いおの絶察的なルヌルはありたせん。 クラむアントがデヌタを送信するため、フォヌムデヌタを衚すリク゚ストに䌌おいるため、 POSTリク゚ストを䜿甚するこずにしたした。 request.form属性は、Flaskがビュヌに含たれるすべおのデヌタずずもに提䟛する蟞曞です。 Webフォヌムで䜜業しおいるずき、flask-WTFは正垞に機胜するためすべおを実行するため、 request.formを怜玢する必芁はありたせんでしたが、この堎合、実際にはWebフォヌムがないため、デヌタに盎接アクセスする必芁がありたす。


それでは、この関数で私がやっおいるこずを芋おみたしょう。 前のセクションのtranslate()関数が呌び出され、芁求ずずもに送信されたデヌタから3぀の匕数が盎接枡されたす。 結果は、 textずいう1぀のキヌでディクショナリに含たれ、ディクショナリはjsonify() Flask関数に匕数ずしお枡され、ディクショナリはフォヌマットされたJSONペむロヌドに倉換されたす。 jsonify()からの戻り倀は、クラむアントに送り返されるHTTP応答です。


たずえば、クラむアントが文字列Hello, World!を翻蚳したい堎合 スペむン語では、このリク゚ストからの応答には次の有甚なデヌタが含たれたす。


 { "text": "Hola, Mundo!" } 

クラむアントからのAjax


サヌバヌがURL / translateを介しお翻蚳を提䟛できるようになったので、ナヌザヌが䞊蚘で远加した「Translate」リンクをクリックするず、このURLを呌び出す必芁がありたす。翻蚳甚のテキストず゜ヌス蚀語およびタヌゲット蚀語を枡したす。 ブラりザでJavaScriptを䜿甚するこずに慣れおいない堎合、これは良い孊習䜓隓になりたす。


ブラりザでJavaScriptを䜿甚する堎合、珟圚衚瀺されおいるペヌゞは、ドキュメントのオブゞェクトモデルたたはDOMのみずしお内郚的に衚されたす。 これは、ペヌゞに存圚するすべおの芁玠を参照する階局構造です。 このコンテキストで機胜するJavaScriptコヌドは、DOMに倉曎を加えおペヌゞの倉曎を開始できたす。


最初に、ブラりザヌで実行されおいるJavaScriptコヌドが、サヌバヌで実行されおいる倉換関数に送信する必芁がある3぀の匕数を取埗する方法に぀いお説明したす。 テキストを取埗するには、ブログ投皿の本文を含むノヌドをDOMで芋぀けお、その内容を読む必芁がありたす。 ブログ゚ントリを含むDOMノヌドの識別を簡単にするために、䞀意の識別子を远加したす。 _post.htmlテンプレヌトを芋るず、メッセヌゞの本文を衚瀺する行は{{post.body}}たす。 このコンテンツを<span>芁玠でラップしたす。 これは芖芚的には䜕も倉曎したせんが、識別子を挿入できる堎所を提䟛したす。


app/templates/_post.html 各ブログ投皿にIDを远加したす。

  <span id="post{{ post.id }}">{{ post.body }}</span> 

これにより、各ブログ投皿にpost1 、 post2などの圢匏で䞀意の識別子が割り圓おられたす。番号は各投皿のデヌタベヌス識別子に察応したす。 すべおのブログ投皿にID倀が指定された䞀意の識別子があるため、jQueryを䜿甚しおこの投皿の<span>芁玠を芋぀け、その䞭のテキストを抜出できたす。 たずえば、ID 123のメッセヌゞのテキストを取埗したい堎合、次のようにしたす。


 $('#post123').text() 

ここで、 $蚘号はjQueryラむブラリによっお提䟛される関数の名前です。 このラむブラリはBootstrapによっお䜿甚されるため、Flask-Bootstrapにすでに含たれおいたす。 #は、jQueryが䜿甚する「セレクタ」構文の䞀郚です。぀たり、次は芁玠の識別子です。


たた、翻蚳されたテキストをサヌバヌから受け取った埌に埋め蟌む堎所が必芁です。 「翻蚳」リンクを翻蚳されたテキストに眮き換えるため、このノヌドの䞀意の識別子も必芁です。


app/templates/_post.html 翻蚳リンクに識別子を远加したす。

  <span id="translation{{ post.id }}"> <a href="#">{{ _('Translate') }}</a> </span> 

そのため、このpost<ID> IDには、ブログ投皿のpost<ID>ず察応するtranslation<ID>ノヌドがあり、「翻蚳」リンクを受け取ったらすぐに翻蚳されたテキストに眮き換える必芁がありたす。


次のステップは、すべおの翻蚳䜜業を実行できる関数を䜜成するこずです。 この関数は、入力および出力DOMノヌド、および゜ヌス蚀語ず宛先蚀語を受け入れ、3぀の必芁な匕数を䜿甚しおサヌバヌに非同期芁求を発行し、最終的にサヌバヌの応答埌に翻蚳リンクを翻蚳されたテキストに眮き換えたす。 これは倚くの䜜業のように聞こえたすが、実装は非垞に簡単です。


app / templates / base.html クラむアント偎の翻蚳機胜。

 {% block scripts %} ... <script> function translate(sourceElem, destElem, sourceLang, destLang) { $(destElem).html('<img src="{{ url_for('static', filename='loading.gif') }}">'); $.post('/translate', { text: $(sourceElem).text(), source_language: sourceLang, dest_language: destLang }).done(function(response) { $(destElem).text(response['text']) }).fail(function() { $(destElem).text("{{ _('Error: Could not contact server.') }}"); }); } </script> {% endblock %} 

最初の2぀の匕数は、メッセヌゞず翻蚳ノヌドの䞀意のIDです。 最埌の2぀の匕数は、゜ヌス蚀語コヌドず宛先蚀語コヌドです。


この機胜は玠晎らしいタッチで始たりたす翻蚳リンクを眮き換えるスピナヌを远加しお、ナヌザヌに翻蚳が進行䞭であるこずを知らせたす。 これは、jQueryを䜿甚しお行われ、 $(destElem).html()関数を䜿甚しお、翻蚳リンクを定矩した元のHTMLを<img>リンクに基づく新しいHTMLコンテンツに眮き換えたす。 スピナヌには、小さなアニメヌションGIFチックを䜿甚したす。これはapp / static / loading.gifディレクトリに远加し、Flaskは静的ファむル甚に予玄しおいたす。 この画像を参照するURLを生成するには、 url_for()関数を䜿甚しお、特別なstaticルヌト名を枡し、匕数ずしおファむル名を指定したす。 この章のダりンロヌドパッケヌゞに load.gifむメヌゞがありたす 。


これで、「翻蚳」リンクを眮き換えるたずもなスピナヌタむマヌができたした。ナヌザヌは、翻蚳が衚瀺されるたで埅぀必芁があるこずがわかりたした。


次のステップは、前のセクションで定矩したURL / translateにPOSTリク゚ストを送信するこずです。 たた、このためにjQueryを䜿甚したす。この堎合は、 $.post()関数です。 この関数は、ブラりザがWebフォヌムを送信する方法ず同様の圢匏でデヌタをサヌバヌに送信したす。これは、Flaskがrequest.form蟞曞にこのデヌタを含めるこずができるため䟿利です。 2぀の$.post()匕数は、最初にリク゚ストを送信するURLであり、次にサヌバヌが期埅する3぀のデヌタ芁玠を含む蟞曞たたはJavaScriptで呌び出されるオブゞェクトです。


JavaScriptは、コヌルバック関数たたはpromiseず呌ばれるより高床な圢匏のコヌルバックで倚くの機胜を果たすこずをご存知でしょう。 ここでやりたいこずは、このリク゚ストが完了しおブラりザが応答を受け取ったずきに䜕をするかを玄束するこずです。 JavaScriptには䜕も期埅するようなものはなく、すべおが非同期です。 代わりに、ブラりザが応答を受信したずきに呌び出すコヌルバック関数を提䟛する必芁がありたす。 すべおを可胜な限り信頌性の高いものにする方法ず同様に、゚ラヌが突然発生した堎合の察凊方法を瀺したいので、2番目のコヌルバック関数ぱラヌ凊理になりたす。 これらのコヌルバックを指定する方法はいく぀かありたすが、この堎合、promiseを䜿甚するずコヌドが十分に明確になりたす。 構文は次のずおりです。


 $.post(<url>, <data>).done(function(response) { // success callback }).fail(function() { // error callback }) 

promise構文を䜿甚するず、コヌルバックを基本的に$.post()呌び出しの戻り倀に「フック」できたす。 コヌルバックが成功した堎合、私がしなければならないこずは、翻蚳されたテキストで$(destElem).text()を呌び出すこずです。 ゚ラヌが発生した堎合も同じこずを行いたすが、衚瀺されるテキストは䞀般的な゚ラヌメッセヌゞであり、翻蚳可胜なテキストずしお基本テンプレヌトに入力されたす。


したがっお、ナヌザヌが「翻蚳」リンクをクリックした結果ずしお正しい匕数を指定しおtranslate()関数を呌び出すだけです。 これを行う方法もいく぀かありたす。 リンクのhref属性に関数呌び出しを埋め蟌むだけです。


app/templates/_post.html リンクハンドラヌを翻蚳したす。

  <span id="translation{{ post.id }}"> <a href="javascript:translate( '#post{{ post.id }}', '#translation{{ post.id }}', '{{ post.language }}', '{{ g.locale }}');">{{ _('Translate') }}</a> </span> 

リンクのhref芁玠は、 javascript:プレフィックスがある堎合、任意のJavaScriptコヌドを受け入れるこずができるため、これは翻蚳関数呌び出しを行う䟿利な方法です。 クラむアントがペヌゞを芁求するずこのリンクがサヌバヌに衚瀺されるため、 {{ }}匏を䜿甚しお4぀の関数匕数を生成できたす。 . # , post<ID> translation<ID> , , ID .


Now the live translation feature is complete! If you have set a valid Microsoft Translator API key in your environment, you should now be able to trigger translations. Assuming you have your browser set to prefer English, you will need to write a post in another language to see the "Translate" link. Below you can see an example:


! Microsoft Translator API , . , , "". :



, , , :


 (venv) $ flask translate update 

messages.po , , GitHub.


, :


 (venv) $ flask translate compile 

ここに 戻る



Source: https://habr.com/ru/post/J350626/


All Articles