ãã®ã¬ã€ãã®ç®çã¯ãããªãæ©èœçãªãã€ã¯ãããã°ã¢ããªã±ãŒã·ã§ã³ãéçºããããšã§ãããªãªãžããªãã£ãå®å šã«æ¬ åŠããŠããããããã€ã¯ãããã°ã¢ããªã±ãŒã·ã§ã³ãšåŒã¶ããšã«ããŸããã
ç®æ¬¡
ããŒã1ïŒHello WorldïŒ
ããŒã2ïŒãã³ãã¬ãŒã
ããŒã3ïŒãã©ãŒã
ããŒã4ïŒããŒã¿ããŒã¹
ããŒã5ïŒãŠãŒã¶ãŒãã°ã€ã³
ããŒã6ïŒãããã£ãŒã«ããŒãžãšã¢ãã¿ãŒ
ããŒã7ïŒåäœãã¹ã
ããŒã8ïŒãã©ãã¯ãŒãé£çµ¡å ãåé
ããŒã9ïŒããŒãžããŒã·ã§ã³
ããŒã10ïŒå šææ€çŽ¢
ããŒã11ïŒã¡ãŒã«ãµããŒã
ããŒã12ïŒåæ§æ
ããŒã13ïŒæ¥ä»ãšæå»
ããŒã14ïŒI18nããã³L10n
ããŒã15ïŒAjaxïŒãã®èšäºïŒ
ããŒã16ïŒãããã°ããã¹ããããã³ãããã¡ã€ãªã³ã°
ããŒã17ïŒLinuxã«ãããã€ïŒRaspberry Piã«ãïŒïŒ
ããŒã18ïŒHeroku Cloudã§ã®ãããã€
ããŒã2ïŒãã³ãã¬ãŒã
ããŒã3ïŒãã©ãŒã
ããŒã4ïŒããŒã¿ããŒã¹
ããŒã5ïŒãŠãŒã¶ãŒãã°ã€ã³
ããŒã6ïŒãããã£ãŒã«ããŒãžãšã¢ãã¿ãŒ
ããŒã7ïŒåäœãã¹ã
ããŒã8ïŒãã©ãã¯ãŒãé£çµ¡å ãåé
ããŒã9ïŒããŒãžããŒã·ã§ã³
ããŒã10ïŒå šææ€çŽ¢
ããŒã11ïŒã¡ãŒã«ãµããŒã
ããŒã12ïŒåæ§æ
ããŒã13ïŒæ¥ä»ãšæå»
ããŒã14ïŒI18nããã³L10n
ããŒã15ïŒAjaxïŒãã®èšäºïŒ
ããŒã16ïŒãããã°ããã¹ããããã³ãããã¡ã€ãªã³ã°
ããŒã17ïŒLinuxã«ãããã€ïŒRaspberry Piã«ãïŒïŒ
ããŒã18ïŒHeroku Cloudã§ã®ãããã€
ããã¯ãåœéåãšããŒã«ãªãŒãŒã·ã§ã³ã«é¢ããæåŸã®èšäºïŒI18nããã³L10nïŒã§ãããéè±èªåãŠãŒã¶ãŒåãã®ãã€ã¯ãããã°ã¢ããªã±ãŒã·ã§ã³ã®å¯çšæ§ãé«ããåãçµã¿ããŸãšããŸãã
ãã®èšäºã§ã¯ãæ £ã芪ããã ãµãŒããŒéçºã®ãã³ã³ãã©ãŒããŸãŒã³ããé¢ãããµãŒããŒã³ã³ããŒãã³ããšã¯ã©ã€ã¢ã³ãã³ã³ããŒãã³ããåæ§ã«éèŠã§ããæ©èœã«åãçµã¿å§ããŸãã äžéšã®ãµã€ãããŠãŒã¶ãŒã³ã³ãã³ãã®æšªã«è¡šç€ºããã翻蚳ããã¿ã³ãèŠãããšããããŸããïŒ ãããã®ãªã³ã¯ã¯ãã³ã³ãã³ãããªã¢ã«ã¿ã€ã ã§ãŠãŒã¶ãŒã®æ¯åœèªã«èªåçã«ç¿»èš³ããŸãã éåžžããªãªãžãã«ã®äžã«ç¿»èš³ãããã³ã³ãã³ããæ¿å ¥ãããŸãã Googleã¯ããã®ã¢ãããŒããå€åœèªã®æ€çŽ¢çµæãFacebookãããã³æçš¿ã«äœ¿çšããŠããŸãã ä»æ¥ã¯ããã€ã¯ãããã°ã«åæ§ã®åäœãè¿œå ããŸãïŒ
ãµãŒããŒåŽãš ã¯ã©ã€ã¢ã³ãåŽ
ãããŸã§åŸã£ãŠããåŸæ¥ã®ã¯ã©ã€ã¢ã³ã/ãµãŒããŒçžäºäœçšã¢ãã«ã§ã¯ããªã¯ãšã¹ãããµãŒããŒã«éä¿¡ããã¯ã©ã€ã¢ã³ãïŒã¯ã©ã€ã¢ã³ãWebãã©ãŠã¶ãŒïŒããããŸãã ãªã¯ãšã¹ãã¯åã«ããã€ãããã£ãŒã«ããªã³ã¯ãã¯ãªãã¯ããå Žåã®ããã«WebããŒãžããªã¯ãšã¹ããããããŠãŒã¶ãŒããããã£ãŒã«ãç·šéããŠãéä¿¡ããã¯ãªãã¯ããå Žåã®ããã«ãµãŒããŒäžã§äœããã®ã¢ã¯ã·ã§ã³ãå®è¡ã§ããŸãã ã¿ã€ãã«é¢ä¿ãªãããµãŒããŒã¯æ°ããããŒãžãã¯ã©ã€ã¢ã³ãã«çŽæ¥éä¿¡ãããããªãã€ã¬ã¯ããä»ããŠéä¿¡ããããšã§ããªã¯ãšã¹ãã«å¿çããŸãã 次ã«ããã©ãŠã¶ã¯çŸåšã®ããŒãžãæ°ããããŒãžã«çœ®ãæããŸãã ãŠãŒã¶ãŒããµã€ãã«ãšã©ãŸã£ãŠããéãããã®ãµã€ã¯ã«ãç¹°ãè¿ãããŸãã ãµãŒããŒãããŒãžãçæãããã¹ãŠã®äœæ¥ãè¡ãããããã®ã¢ãã«ãããµãŒããŒããšåŒã³ãŸãããã¯ã©ã€ã¢ã³ãã¯åä¿¡ããããŒãžã衚瀺ããã ãã§ãã
ãã¯ã©ã€ã¢ã³ããã¢ãã«ã§ã¯ããµãŒããŒã«ãªã¯ãšã¹ããéä¿¡ãããã©ãŠã¶ãŒããŸã ãããŸãã ãµãŒããŒã¯ãããµãŒããŒãã¢ãã«ã®äœ¿çšæã«çºçãããã®ãšåæ§ã®ããŒãžã§å¿çããŸããããã¹ãŠã®ããŒã¿ãHTMLã§ã¯ãªããäž»ã«javascriptã®ã³ãŒãããããŸãã ã¯ã©ã€ã¢ã³ããããŒãžãåä¿¡ãããšããã«ãã¯ã©ã€ã¢ã³ãã¯ããã衚瀺ããããŒãžã®ä»£ããã«ä»å±ã®ã³ãŒããå®è¡ããŸãã ããã§ããµãŒããŒãšã®ç¶ç¶çãªå¯Ÿè©±ãªãã§åäœã§ããã¢ã¯ãã£ããªã¯ã©ã€ã¢ã³ããã§ããŸããã çæ³çãªå Žåãã¢ããªã±ãŒã·ã§ã³ã¯æåã®ããŒãæã«ã¯ã©ã€ã¢ã³ãã«ããŠã³ããŒãããããã®åŸãããŒãžãæŽæ°ããªããŠãã¯ã©ã€ã¢ã³ãäžã§èµ·åããŠåäœããããŒã¿ãåä¿¡ããã³ä¿åããããã ãã«ãµãŒããŒãšå¯Ÿè©±ããŸãã ãã®ã¿ã€ãã®ã¢ããªã±ãŒã·ã§ã³ã¯ã ã·ã³ã°ã«ããŒãžã¢ããªã±ãŒã·ã§ã³ãŸãã¯SPAãšåŒã°ããŸãã
ã»ãšãã©ã®å®éã®ã¢ããªã±ãŒã·ã§ã³ã¯ãããã2ã€ã®ã¢ãããŒãã®çµã¿åããã§ãã çŸæç¹ã§ã¯ãã¢ããªã±ãŒã·ã§ã³ã¯å®å šã«ãµãŒããŒäžã§å®è¡ãããŸãããä»æ¥ã¯ã¯ã©ã€ã¢ã³ãåŽã«ããã€ãã®ããžãã¯ãè¿œå ããŸãã æçš¿ããªã¢ã«ã¿ã€ã ã§ç¿»èš³ããããã«ããã©ãŠã¶ãŒã¯ãµãŒããŒã«ãªã¯ãšã¹ããéä¿¡ããŸããããµãŒããŒã¯ã¯ã©ã€ã¢ã³ãäžã§ããŒãžãæŽæ°ããã«ç¿»èš³ãããããã¹ãã§å¿çããŸãã ã¯ã©ã€ã¢ã³ãã¯ãçŸåšã®ããŒãžã«ç¿»èš³ãåçã«è¿œå ããŸãã ãã®ææ³ã¯AjaxãšããŠç¥ãããŠãããAsynchronous JavascriptãšXMLã®ç¥ã§ãïŒä»æ¥ã§ã¯XMLã¯ãã°ãã°JSONã«çœ®ãæããããŸããïŒã
ã«ã¹ã¿ã ã³ã³ãã³ã翻蚳
çŸæç¹ã§ã¯ãFlask-Babelã®ãããã§ãå€åœèªã®ãµããŒãã¯ããªãè¯å¥œã§ãã èšå€§ãªæ°ã®èšèªã§ã¢ããªã±ãŒã·ã§ã³ãå ¬éã§ããŸããããªãã¯ç§ãã¡ãå©ããæºåãã§ããŠãã翻蚳è ãèŠã€ããå¿ èŠããããŸãã
ããããäžç¬éããŸããã ç°ãªãèšèªã話ããŠãŒã¶ãŒãã¢ããªã±ãŒã·ã§ã³ãå©çšã§ããããã«ããã®ã§ãããããä»ããããããç°ãªãèšèªã®ã¬ã³ãŒããåœã«è¡šç€ºãããããã«ãªããŸãã ãããŠä»ãç§ãã¡ã®ãŠãŒã¶ãŒã¯ãèšé²ãèŠãŠãããšãã«ã圌ããç解ããŠããªãèšèªã®èšé²ã«ééããå¯èœæ§ããããŸãã èªå翻蚳æ©èœãæäŸããã®ã¯ããããšã§ãããïŒ èªå翻蚳ã®å質ã¯ããã»ã©é«ããããŸããããã»ãšãã©ã®å Žåãæžãããå 容ã®æå³ãç解ããã ãã§ååã§ããããããã¹ãŠã®ãŠãŒã¶ãŒïŒç§ãã¡ãå«ãïŒããã®ãããªæ©èœã®æ©æµãåããããšãã§ããŸãã
ãã®æ©èœã¯ãAjaxã§å®è£ ããã®ã«çæ³çã§ãã ã¡ã€ã³ããŒãžã«ç°ãªãèšèªã®è€æ°ã®æçš¿ãå«ãŸããŠãããšããŸãã åŸæ¥ã®æ¹æ³ã§æçš¿ã®ç¿»èš³ãå®è£ ããå Žåãæçš¿ã翻蚳ãããªã¯ãšã¹ãã«ãããçŸåšã®ããŒãžãéžæããæçš¿ã®ç¿»èš³ãå«ãæ°ããããŒãžã«çœ®ãæããããŸãã èªãã åŸããŠãŒã¶ãŒã¯ãæ»ãããã¿ã³ãã¯ãªãã¯ããŠãã¹ãŠã®æçš¿ã®ãªã¹ãã«æ»ãå¿ èŠããããŸãã å®éã«ã¯ã翻蚳åŸã®ãªã¯ãšã¹ãã¯ãããŒãžå šäœãæŽæ°ããããã®éèŠãªã¿ã¹ã¯ã§ã¯ãããŸããã 翻蚳ãããããã¹ããå ã®æçš¿ããã¹ãã®äžã«åã«æ¿å ¥ããæ®ãã®ã³ã³ãã³ãããã®ãŸãŸæ®ããæ¹ãè¯ãã§ãããã ãããã£ãŠãä»æ¥ã¯æåã®AjaxãµãŒãã¹ãå®è£ ããŠããŸãïŒ
èªå翻蚳ãå®è£ ããã«ã¯ãããã€ãã®æé ãå¿ èŠã§ãã ãŸãã翻蚳ããæçš¿ã®èšèªã決å®ããå¿ èŠããããŸãã æçš¿ã®èšèªãç¥ã£ãŠããã°ããŠãŒã¶ãŒãéžæããèšèªãç¥ã£ãŠãããããç¹å®ã®ãŠãŒã¶ãŒã«ç¿»èš³ãå¿ èŠãã©ããã調ã¹ãããšãã§ããŸãã 翻蚳ãå¿ èŠã§ããŠãŒã¶ãŒãããã衚瀺ãããå Žåã¯ããµãŒããŒã§å®è¡ãããAjax翻蚳ãµãŒãã¹ã䜿çšããŸãã ãã®çµæãã¯ã©ã€ã¢ã³ãåŽã®javascriptã¯ãæçš¿ã®ç¿»èš³ãããŒãžã«è¿œå ããŸãã
æçš¿èšèªã®å®çŸ©
æåã®ã¿ã¹ã¯ã¯ãæçš¿ã®ãœãŒã¹èšèªã決å®ããããšã§ãã èšèªãæ£ç¢ºã«æ±ºå®ããããšã¯åžžã«å¯èœã§ãããšã¯éããªãããããã®ããã«å¯èœãªéãã®ããšããã¹ãŠå®è¡ããããšããŸãã ãã®åé¡ã解決ããã«ã¯ã guess-languageã¢ãžã¥ãŒã«ã䜿çšããŸãã ããã§ã¯ã€ã³ã¹ããŒã«ããŸãããã Linuxããã³Mac OS XãŠãŒã¶ãŒïŒ
flask/bin/pip install guess-language
WindowsãŠãŒã¶ãŒïŒ
flask\Scripts\pip install guess-language
ãã®ã¢ãžã¥ãŒã«ã䜿çšããŠãåæçš¿ã®ããã¹ããã¹ãã£ã³ããèšèªã決å®ããããšããŸãã ãªããªã åãæçš¿ãäœåºŠãã¹ãã£ã³ããå¿ èŠã¯ãããŸããããŠãŒã¶ãŒãéä¿¡ããæçš¿ããšã«ããã1åè¡ããŸãã 次ã«ãæçš¿èšèªæ å ±ãšæçš¿èªäœãããŒã¿ããŒã¹ã«ä¿åããŸãã
PostsããŒãã«ã«èšèªãã£ãŒã«ããè¿œå ããŸãããã
class Post(db.Model): __searchable__ = ['body'] id = db.Column(db.Integer, primary_key = True) body = db.Column(db.String(140)) timestamp = db.Column(db.DateTime) user_id = db.Column(db.Integer, db.ForeignKey('user.id')) language = db.Column(db.String(5))
ããŒã¿ããŒã¹ãå€æŽãããã³ã«ã移è¡ãå¿ããŠã¯ãªããŸããã
$ ./db_migrate.py New migration saved as microblog/db_repository/versions/005_migration.py Current database version: 5
æçš¿èšèªæ å ±ãä¿åããå Žæãã§ããã®ã§ãæ°ããæçš¿ãè¿œå ããããã»ã¹ã«èšèªå®çŸ©ãè¿œå ããŸãããã
from guess_language import guessLanguage @app.route('/', methods = ['GET', 'POST']) @app.route('/index', methods = ['GET', 'POST']) @app.route('/index/<int:page>', methods = ['GET', 'POST']) @login_required def index(page = 1): form = PostForm() if form.validate_on_submit(): language = guessLanguage(form.post.data) if language == 'UNKNOWN' or len(language) > 5: language = '' post = Post(body = form.post.data, timestamp = datetime.utcnow(), author = g.user, language = language) db.session.add(post) db.session.commit() flash(gettext('Your post is now live!')) return redirect(url_for('index')) posts = g.user.followed_posts().paginate(page, POSTS_PER_PAGE, False) return render_template('index.html', title = 'Home', form = form, posts = posts)
æçš¿ã®èšèªãèŠã€ããããšãã§ããªãã£ãå ŽåããŸãã¯äºæ³å€ã«é·ãçµæãè¿ãããå Žåãèšèªãã£ãŒã«ãã«ç©ºã®æååãä¿åããŸãã ããã¯ãæçš¿ã®èšèªãããããªãããŒã«ãŒã«ãªããŸãã
翻蚳ãªã³ã¯ã衚瀺ãã
次ã®ã¹ãããã¯ããŠãŒã¶ãŒã䜿çšããèšèªïŒfile app / templates / post.htmlïŒä»¥å€ã®èšèªã§æžãããåæçš¿ã®ã翻蚳ããªã³ã¯ã衚瀺ããããšã§ãïŒ
{% if post.language != None and post.language != '' and post.language != g.locale %} <div><a href="#">{{ _('Translate') }}</a></div> {% endif %}
ãããpost.htmlãã³ãã¬ãŒãã§è¡ããæçš¿ã衚瀺ãããã¹ãŠã®ããŒãžã«ç¿»èš³æ©èœãè¿œå ããŸããã æçš¿ã®èšèªãç¹å®ã§ããç¹å®ã®èšèªãFlask-Babelã®localeselectoré¢æ°ã«ãã£ãŠè¿ãããg.localeããã¢ã¯ã»ã¹ã§ããèšèªãšç°ãªãå Žåãã翻蚳ããªã³ã¯ã衚瀺ãããŸãã
ãã®ãªã³ã¯ã«ã¯ãæ°ããããã¹ãã§ãããTranslateããšããåèªãè¿œå ããå¿ èŠããããŸããããã¯ç¿»èš³ãã¡ã€ã«ã«å«ããå¿ èŠããããŸãã ããã«æååã_ïŒïŒé¢æ°ã§ã©ããããŠããã®æååãFlask-Babelçšã«ããŒã¯ããŸãã ãã®åèªã翻蚳ããã«ã¯ã åã®èšäºã§è¡ã£ãããã«ãèšèªãªãã¡ã¬ã³ã¹ïŒtr_update.pyïŒãæŽæ°ããpoeditãšã³ã³ãã€ã«ã䜿çšããŠç¿»èš³ïŒtr_compile.pyïŒããå¿ èŠããããŸãã
çŸæç¹ã§ã¯ã翻蚳ãéå§ããããã«äœããã¹ããããããªããããçŸæç¹ã§ã¯ãªã³ã¯ã¯ã¹ã¿ãã«ãªããŸãã
翻蚳ãµãŒãã¹
å ã«é²ãåã«ã翻蚳ãµãŒãã¹ãéžæããå¿ èŠããããŸãã
翻蚳ãµãŒãã¹ãæäŸãããµãŒãã¹ã¯æ°å€ããããŸãããæ®å¿µãªããããããã®ã»ãšãã©ã¯ææã§ããããããªãã®å¶éããããŸãã
2ã€ã®äž»èŠãªç¿»èš³ãµãŒãã¹ã¯ã Google TranslateãšMicrosoft Translatorã§ãã ã©ã¡ããææã§ãããMicrosoftã¯å°éã®ç¿»èš³ãå«ãç¡æã®ãã©ã³ãæäŸããŠããŸãã Googleã¯ãããŸã§ç¡æ翻蚳ãæäŸããŠããŸããããæäŸããŠããŸããã ããã«ããããµãŒãã¹ãéžæãããããªããŸãã
Microsoft Translator Serviceã䜿çšãã
Microsoft Translatorã䜿çšããããã®å€ãã®èŠä»¶ããããŸãã
- ã¢ããªã±ãŒã·ã§ã³éçºè ã¯ãAzure Marketplaceã®Microsoft Translatorã¢ããªã«ç»é²ããå¿ èŠããããŸãã ããã§ãæéãã©ã³ãéžæã§ããŸãïŒç¡æã¯äžçªäžã«ãããŸãïŒã
- 次ã«ãéçºè ã¯ã¢ããªã±ãŒã·ã§ã³ãç»é²ããå¿ èŠããããŸã ã ç»é²ãããã¢ããªã±ãŒã·ã§ã³ã«ã¯ããµãŒãã¹ã«ãªã¯ãšã¹ããéä¿¡ãããšãã«äœ¿çšãããã¯ã©ã€ã¢ã³ãIDãšã¯ã©ã€ã¢ã³ãã·ãŒã¯ã¬ããã³ãŒããäžããããŸãã
ç»é²ãå®äºããåŸã転éèŠæ±ããã»ã¹ã¯æ¬¡ã®ãšããã§ãã
- ã¯ã©ã€ã¢ã³ãIDãšã·ãŒã¯ã¬ãããæž¡ãããšã§ã¢ã¯ã»ã¹ããŒã¯ã³ãååŸããŸã ã
- åªå ã¡ãœãã-Ajax ã HTTPãŸãã¯SOAPãåŒã³åºã ãã¢ã¯ã»ã¹ããŒã¯ã³ãšç¿»èš³çšã®ããã¹ããæž¡ããŸãã
å®éã«ã¯ãå®éãããè€éã«èãããŸãã 詳现ã説æããããšãªãããã¹ãŠã®äœæ¥ãå®è¡ããããã¹ããå¥ã®èšèªïŒapp / translate.pyãã¡ã€ã«ïŒã«ç¿»èš³ããé¢æ°ã次ã«ç€ºããŸãã
import urllib, httplib import json from flask.ext.babel import gettext from config import MS_TRANSLATOR_CLIENT_ID, MS_TRANSLATOR_CLIENT_SECRET def microsoft_translate(text, sourceLang, destLang): if MS_TRANSLATOR_CLIENT_ID == "" or MS_TRANSLATOR_CLIENT_SECRET == "": return gettext('Error: translation service not configured.') try: # get access token params = urllib.urlencode({ 'client_id': MS_TRANSLATOR_CLIENT_ID, 'client_secret': MS_TRANSLATOR_CLIENT_SECRET, 'scope': 'http://api.microsofttranslator.com', 'grant_type': 'client_credentials' }) conn = httplib.HTTPSConnection("datamarket.accesscontrol.windows.net") conn.request("POST", "/v2/OAuth2-13", params) response = json.loads (conn.getresponse().read()) token = response[u'access_token'] # translate conn = httplib.HTTPConnection('api.microsofttranslator.com') params = { 'appId': 'Bearer ' + token, 'from': sourceLang, 'to': destLang, 'text': text.encode("utf-8") } conn.request("GET", '/V2/Ajax.svc/Translate?' + urllib.urlencode(params)) response = json.loads("{\"response\":" + conn.getresponse().read().decode('utf-8-sig') + "}") return response["response"] except: return gettext('Error: Unexpected error.')
ãã®é¢æ°ã¯ãæ§æãã¡ã€ã«ãã2ã€ã®æ°ããèŠçŽ ãMicrosoftããæäŸãããIDãšã·ãŒã¯ã¬ããã³ãŒãïŒconfig.pyãã¡ã€ã«ïŒãã€ã³ããŒãããŸãã
# microsoft translation service MS_TRANSLATOR_CLIENT_ID = '' # app id MS_TRANSLATOR_CLIENT_SECRET = '' # secret
ãµãŒãã¹ã䜿çšããã«ã¯ãèªåã§ç»é²ãããããã®æ§æå€æ°ã®ããŒã¿ãåä¿¡ããã¢ããªã±ãŒã·ã§ã³ãç»é²ããå¿ èŠããããŸãã ãã€ã¯ãããã°ããã¹ãããã ãã®å Žåã§ããç»é²ããå¿ èŠããããŸãïŒç¡æã§ãïŒã
æ°ããããã¹ã-ãšã©ãŒã¡ãã»ãŒãžãè¿œå ããŸããã ããŒã«ã©ã€ãºããå¿ èŠããããããtr_update.pyãpoeditãtr_compile.pyãå床å®è¡ããŠç¿»èš³ãã¡ã€ã«ãæŽæ°ããŸãã
äœãã翻蚳ããŸãããïŒ
ã§ã¯ã翻蚳ãµãŒãã¹ãã©ã®ããã«äœ¿çšããŸããïŒ å®éãããã¯ç°¡åã§ãã 以äžã«äŸã瀺ããŸãã
$ flask/bin/python Python 2.6.8 (unknown, Jun 9 2012, 11:30:32) >>> from app import translate >>> translate.microsoft_translate('Hi, how are you today?', 'en', 'es') u'¿Hola, cómo estás hoy?'
ãµãŒããŒäžã®Ajax
ããã§ãããèšèªã®ããã¹ããå¥ã®èšèªã«ç¿»èš³ã§ããŸãã ãã®æ©èœãã¢ããªã±ãŒã·ã§ã³ã«çµ±åããæºåãæŽããŸããã
ãŠãŒã¶ãŒãæçš¿ã®ã翻蚳ããªã³ã¯ãã¯ãªãã¯ãããšãAjaxãªã¯ãšã¹ãããµãŒããŒã«éä¿¡ãããŸãã ãã®èŠæ±ãéä¿¡ããæ¹æ³ã«ã€ããŠã¯åŸã»ã©èª¬æããŸãããä»åºŠã¯ãµãŒããŒåŽã®èŠæ±åŠçã«çŠç¹ãåœãŠãŸãããã
ãµãŒããŒäžã®AjaxãµãŒãã¹ã¯ãHTMLããŒãžããªãã€ã¬ã¯ãã®ä»£ããã«ãéåžžã¯XMLãŸãã¯JSON圢åŒã®ããŒã¿ãè¿ããšãã1ã€ã®éããããéåžžã®ãã¬ãŒã³ããŒã·ã§ã³æ©èœã§ã ã JSONã¯Javascriptã«ããè¿ãããããã®åœ¢åŒïŒãã¡ã€ã«app / views.pyïŒã䜿çšããŸãã
from flask import jsonify from translate import microsoft_translate @app.route('/translate', methods = ['POST']) @login_required def translate(): return jsonify({ 'text': microsoft_translate( request.form['text'], request.form['sourceLang'], request.form['destLang']) })
ããã»ã©æ°ãããã®ã¯ãããŸããã ãã®ãã¥ãŒã¯POSTãªã¯ãšã¹ããåŠçããŸããPOSTãªã¯ãšã¹ãã«ã¯ã翻蚳ããããã¹ããšãå ã®èšèªãšããã¹ãã®ç¿»èš³å ã®èšèªã®ã³ãŒããå«ãŸããŠããå¿ èŠããããŸãã ããã¯POSTãªã¯ãšã¹ãã§ãããããrequest.formèŸæžã䜿çšããŠHTMLãã©ãŒã ããéä¿¡ããããã®ããã«ãã®ããŒã¿ã«ã¢ã¯ã»ã¹ããŸãã ãã®ããŒã¿ã䜿çšããŠç¿»èš³é¢æ°ã®1ã€ãåŒã³åºãã翻蚳ãåãåã£ãåŸãFlaské¢æ°jsonifyïŒïŒã䜿çšããŠå¿çãJSONã«å€æããŸãã ã¯ã©ã€ã¢ã³ãããªã¯ãšã¹ããžã®åçãšããŠè¡šç€ºããããŒã¿ã¯ã次ã®åœ¢åŒã«ãªããŸãã
{ "text": "< >" }
ã¯ã©ã€ã¢ã³ãäžã®Ajax
ããã§ããã©ãŠã¶ãŒããAjaxãã¥ãŒé¢æ°ãåŒã³åºãå¿ èŠããããããpost.htmlãã³ãã¬ãŒãã«æ»ãã以åã«éå§ããããšãå®äºããŸãã
ãŸããæçš¿ã®ããã¹ããäžæã®IDãæã€spanèŠçŽ ã§å²ã¿ãåŸã§DOMïŒãã¡ã€ã«app / templates / post.htmlïŒã§ç°¡åã«èŠã€ããããããã«ããŸãã
<p><strong><span id="post{{post.id}}">{{post.body}}</span></strong></p>
æçš¿IDã䜿çšããŠäžæã®IDãäœæããããšã«æ³šæããŠãã ããã æçš¿ã®IDã3ã®å ŽåãèŠçŽ ã®IDã¯post3ã«ãªããŸãã
ãŸãã翻蚳ã衚瀺ãããåŸã«ãã®ãªã³ã¯ãé衚瀺ã«ã§ããããã«ãäžæã®IDãæã€ã翻蚳ããªã³ã¯ãã¹ãã³ã«é 眮ããŸãã
<div><span id="translation{{post.id}}"><a href="#">{{ _('Translate') }}</a></span></div>
äžèšã®äŸãšåæ§ã«ã翻蚳ãªã³ã¯ã¯idãtranslation3ã®èŠçŽ ã«ãããŸãã
ãŸãããŠãŒã¶ãŒã®é åãšå©äŸ¿æ§ãé«ããããã«ã翻蚳ããã»ã¹ããµãŒããŒã§å®è¡ãããŠããããšããŠãŒã¶ãŒã«éç¥ããã¢ãã¡ãŒã·ã§ã³ãè¿œå ããŸãã ããŒãžã®èªã¿èŸŒã¿åŸã«é衚瀺ã«ãªãã翻蚳äžã®ã¿è¡šç€ºãããäžæã®IDãæã¡ãŸãã
<img id="loading{{post.id}}" style="display: none" src="/static/img/loading.gif">
ã ããä»ãç§ãã¡ã¯æã£ãŠããŸãïŒ
- 翻蚳ããããã¹ããå«ãpost <id>ã«çããidãæã€èŠçŽ ã
- ã翻蚳ããªã³ã¯ãå«ã翻蚳<id>ãšçããidãæã€èŠçŽ ã§ãåŸã§ç¿»èš³ãããããã¹ãã«çœ®ãæããããŸã
- ãããŠãããŒãäžã®<id>ã«çããidã®ç»åã¯ã翻蚳äžã«è¡šç€ºãããŸãã
æ¥å°ŸèŸ<id>ã¯ããããã®èŠçŽ ãäžæã«ããŸãã ããŒãžã«ã¯ããã€ã§ãæçš¿ããããšãã§ãããããã¯ãã¹ãŠããã3ã€ã®å€ã®ç¬èªã®ã»ãããæã¡ãŸãã
次ã«ãã転éããªã³ã¯ãã¯ãªãã¯ããŠãAjaxã«ãªã¯ãšã¹ããéä¿¡ããå¿ èŠããããŸãã ãããè¡ãã«ã¯ããã¹ãŠã®äœæ¥ãå®è¡ããJavascripté¢æ°ãäœæããŸãã ã翻蚳ããªã³ã¯ãã¯ãªãã¯ããŠé¢æ°åŒã³åºããè¿œå ããããšããå§ããŸãããã
<a href="javascript:translate('{{post.language}}', '{{g.locale}}', '#post{{post.id}}', '#translation{{post.id}}', '#loading{{post.id}}');">{{ _('Translate') }}</a>
ãã³ãã¬ãŒãå€æ°ã¯å°ããããã«ããã§ãããé¢æ°åŒã³åºãèªäœã¯éåžžã«ç°¡åã§ãã ã¹ãã€ã³èªã§æžãããè±èªçã®ãµã€ãã䜿çšããŠãŠãŒã¶ãŒãé²èŠ§ããid = 23ã®æçš¿ãæ€èšããŠãã ããã ãã®å Žåãé¢æ°ã¯æ¬¡ã®ããã«åŒã³åºãããŸãã
translate('es', 'en', '#post23', '#translation23', '#loading23')
ã€ãŸã ãã®é¢æ°ã¯ãå ã®èšèªãšå®å èšèªãããã³3ã€ã®ãã¹ãé¢é£èŠçŽ ã®ã»ã¬ã¯ã¿ãŒãåãåããŸãã
åæçš¿ã衚瀺ããããã«äœ¿çšããããããé¢æ°åŒã³åºããpost.htmlãã³ãã¬ãŒãã«çŽæ¥è¿œå ããŸããã ã¢ããªã±ãŒã·ã§ã³ã®ãã¹ãŠã®ããŒãžïŒãã¡ã€ã«app / templates / base.htmlïŒã§ã¢ã¯ã»ã¹ã§ããããã«ãåºæ¬ãã³ãã¬ãŒãã«é¢æ°èªäœãäœæããŸãã
<script> function translate(sourceLang, destLang, sourceId, destId, loadingId) { $(destId).hide(); $(loadingId).show(); $.post('/translate', { text: $(sourceId).text(), sourceLang: sourceLang, destLang: destLang }).done(function(translated) { $(destId).text(translated['text']) $(loadingId).hide(); $(destId).show(); }).fail(function() { $(destId).text("{{ _('Error: Could not contact server.') }}"); $(loadingId).hide(); $(destId).show(); }); } </script>
å¿ èŠãªæ©èœãå®è£ ããã«ã¯ãjQueryã䜿çšããŸãã Bootstrapãæ¥ç¶ãããšãã«jQueryãæ¥ç¶ããããšãæãåºãããŠãã ããã
翻蚳ãªã³ã¯ãé衚瀺ã«ããããŠã³ããŒãã®é²è¡ç¶æ³ããŒã衚瀺ããããšããå§ããŸãã
次ã«ã$ .postïŒïŒé¢æ°ã䜿çšããŠãAjaxãªã¯ãšã¹ãããµãŒããŒã«éä¿¡ããŸãã $ .posté¢æ°ã¯POSTèŠæ±ãéä¿¡ããŸããããã¯ããµãŒããŒããã©ãŒã ãéä¿¡ãããšãã«ãã©ãŠã¶ãŒããéä¿¡ãããèŠæ±ãšåºå¥ã§ããªããªããŸãã éãã¯ãã¯ã©ã€ã¢ã³ãã§ã¯ãã®ãªã¯ãšã¹ããããŒãžå šäœããªããŒãããããšãªãããã¯ã°ã©ãŠã³ãã§éä¿¡ãããããšã§ãã ãµãŒããŒããå¿çãåä¿¡ãããšãdoneïŒïŒé¢æ°ãžã®åŒæ°ã§ããé¢æ°ãå®è¡ãããåä¿¡ããããŒã¿ãããŒãžã«æ¿å ¥ããããšããŸãã ãã®é¢æ°ã¯ãå¿çãåŒæ°ãšããŠåãåããŸãã DOMã®ã翻蚳ããªã³ã¯ã翻蚳ãããããã¹ãã«çœ®ãæããããŠã³ããŒãã€ã³ãžã±ãŒã¿ãŒãé衚瀺ã«ããŠãæåŸã«ç¿»èš³ãããããã¹ãããŠãŒã¶ãŒã«è¡šç€ºããã ãã§ãã ã§ããïŒ
ã¯ã©ã€ã¢ã³ãããµãŒããŒããã®å¿çãåä¿¡ã§ããªãåå ãçºçããå ŽåãfailïŒïŒé¢æ°ã®åŒæ°ã§ããé¢æ°ãå®è¡ãããŸãã ãã®å ŽåããµããŒããããŠãããã¹ãŠã®èšèªã«ç¿»èš³ãã翻蚳ããŒã¿ããŒã¹ãæŽæ°ããå¿ èŠããããšã©ãŒã¡ãã»ãŒãžã衚瀺ããã ãã§ãã
åäœãã¹ã
ãã¹ããã¬ãŒã ã¯ãŒã¯ãèŠããŠããŸããïŒ ã¢ããªã±ãŒã·ã§ã³ã«æ°ããã³ãŒããè¿œå ããåŸã¯åžžã«ããã®ã³ãŒãã®ãã¹ããäœæããããšãçã«ããªã£ãŠãããã©ãããè©äŸ¡ãã䟡å€ããããŸãã 翻蚳ãµãŒãã¹ãžã®ã¢ããŒã«ã¯ãã³ãŒãã®ãã®åŸã®äœæ¥ã®éçšã§ããŸãã¯ãµãŒãã¹èªäœã®äœæ¥ã®æŽæ°ã®çµæãšããŠãåœç€Ÿã«ãã£ãŠç Žãããå ŽåããããŸãã ãµãŒãã¹ã«ã¢ã¯ã»ã¹ãã翻蚳ãååŸã§ããããšã確èªããç°¡åãªãã¹ããäœæããŸãããã
from app.translate import microsoft_translate class TestCase(unittest.TestCase): #... def test_translation(self): assert microsoft_translate(u'English', 'en', 'es') == u'Inglés' assert microsoft_translate(u'Español', 'es', 'en') == u'Spanish'
çŸæç¹ã§ã¯ãã¯ã©ã€ã¢ã³ãåŽã®ã³ãŒãããã¹ãããããã®ãã¬ãŒã ã¯ãŒã¯ããªããããAjaxãªã¯ãšã¹ããµã€ã¯ã«å šäœããã¹ãããŸããã
å®è¡äžã®ãã¹ãã¯ãšã©ãŒãªãã§åæ Œããã¯ãã§ãïŒ
$ ./tests.py ..... ---------------------------------------------------------------------- Ran 5 tests in 5.932s OK
ãã ããMicrosoft Translatorã®ã¢ã¯ã»ã¹ããŒã¿ãæå®ããåã«ãã¹ããå®è¡ãããšã次ã®çµæãåŸãããŸãã
$ ./tests.py ....F ====================================================================== FAIL: test_translation (__main__.TestCase) ---------------------------------------------------------------------- Traceback (most recent call last): File "./tests.py", line 120, in test_translation assert microsoft_translate(u'English', 'en', 'es') == u'Inglés' AssertionError ---------------------------------------------------------------------- Ran 5 tests in 3.877s FAILED (failures=1)
ãããã«
ããã§ããã®èšäºãçµäºããŸãã èšäºãæžããŠããã ãã®ãšåãããã楜ããã§ããã ããã幞ãã§ãïŒ
æè¿ãå šææ€çŽ¢ã«Flask-WhooshAlchemyã䜿çšããéã®ããŒã¿ããŒã¹ã®åé¡ã«ã€ããŠéç¥ãåããŸããã 次ã®èšäºã§ã¯ããã®åé¡ãå£å®ãšããŠäœ¿çšããŠãFlaskã¢ããªã±ãŒã·ã§ã³ãæäœããéã®ãããã°ææ³ã®ããã€ããæãäžããŸãã ããŒãXVIãæåŸ ããŠãã ããïŒ
ææ°ã®ãã€ã¯ãããã°ããŒãžã§ã³ãžã®ãªã³ã¯ã¯æ¬¡ã®ãšããã§ãã
microblog-0.15.zipãããŠã³ããŒãããŸãã
ãŸãã¯ã GitHubã§ãœãŒã¹ã³ãŒããèŠã€ããããšãã§ããŸãã
ãã²ã«