{"id":20619783,"url":"https://github.com/twtrubiks/django-translation-tutorial","last_synced_at":"2025-09-07T22:37:58.645Z","repository":{"id":84518932,"uuid":"147498885","full_name":"twtrubiks/django-translation-tutorial","owner":"twtrubiks","description":"How to use Django to implement translations 📝","archived":false,"fork":false,"pushed_at":"2018-09-05T13:11:52.000Z","size":17,"stargazers_count":14,"open_issues_count":0,"forks_count":2,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-04-15T12:17:18.467Z","etag":null,"topics":["django","translations","tutorial"],"latest_commit_sha":null,"homepage":null,"language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/twtrubiks.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2018-09-05T10:11:36.000Z","updated_at":"2024-12-02T02:05:20.000Z","dependencies_parsed_at":"2023-03-02T04:30:27.326Z","dependency_job_id":null,"html_url":"https://github.com/twtrubiks/django-translation-tutorial","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/twtrubiks/django-translation-tutorial","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/twtrubiks%2Fdjango-translation-tutorial","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/twtrubiks%2Fdjango-translation-tutorial/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/twtrubiks%2Fdjango-translation-tutorial/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/twtrubiks%2Fdjango-translation-tutorial/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/twtrubiks","download_url":"https://codeload.github.com/twtrubiks/django-translation-tutorial/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/twtrubiks%2Fdjango-translation-tutorial/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":274107701,"owners_count":25223451,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-09-07T02:00:09.463Z","response_time":67,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["django","translations","tutorial"],"created_at":"2024-11-16T12:12:30.385Z","updated_at":"2025-09-07T22:37:58.619Z","avatar_url":"https://github.com/twtrubiks.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# django-translation-tutorial\n\n如何使用 Django 實作 translation  📝\n\n* [Youtube Tutorial PART 1 - django-translation-tutorial](https://youtu.be/9zFCfnVgXjs)\n\n* [Youtube Tutorial PART 2 - django-translation-tutorial](https://youtu.be/sz0cpt8I1fM)\n\n* [Youtube Tutorial PART 3 - django-translation-tutorial](https://youtu.be/9njecageJvM)\n\n## 簡介\n\n本篇文章將介紹如何使用 Django 實作 translation ，我參考了 Django 官網的 [translation 文件](https://docs.djangoproject.com/en/2.1/topics/i18n/translation/)，\n\n並且紀錄了一些細節。如果你想用 Flask 實作的話，可參考我之前寫的文章 [Flask-Babel-example](https://github.com/twtrubiks/Flask-Babel-example)。\n\n建議閱讀此篇文章之前，要對 docker 有一些基本的認識，如果你對 docker 不熟，建議可參考\n\n[Docker 基本教學 - 從無到有 Docker-Beginners-Guide](https://github.com/twtrubiks/docker-tutorial)，為什麼會使用到 docker :question:\n\n因為本身電腦是 windows，而 Django translation 需要安裝 `gettext`，我在 windows 中一直裝不起來，\n\n所以最後果斷使用 docker :sweat_smile:\n\n## 建立環境\n\n我使用 docker 建立環境，先來看一下 [Dockerfile](https://github.com/twtrubiks/django-translation-tutorial/blob/master/django_translation/Dockerfile)，\n\n```text\nFROM python:3.6.2\nLABEL maintainer twtrubiks\nENV PYTHONUNBUFFERED 1\nRUN mkdir /docker_tutorial\nWORKDIR /docker_tutorial\nCOPY . /docker_tutorial/\nRUN pip install -r requirements.txt\nRUN apt-get update \u0026\u0026 \\\n    apt-get install -y gettext \u0026\u0026 \\\n    apt-get clean \u0026\u0026 rm -rf /var/cache/apt/* \u0026\u0026 rm -rf /var/lib/apt/lists/* \u0026\u0026 rm -rf /tmp/*\n```\n\n最重要的就是 `apt-get install -y gettext` 這個，我會用 docker 也是因為這個原因，windows 一直裝不起來阿:cry:\n\n如果你是 Linux 或是 MAC，應該就不需要用 docker 了，本機理論上很好安裝。\n\n接著執行以下指令建立環境，\n\n```cmd\ndocker-compose build\n```\n\n再啟動環境 ( 其實也可以直接執行這個就好 )，\n\n```cmd\ndocker-compose up\n```\n\n再來進入 docker 環境中 migrate，\n\n```python\npython manage.py migrate\n```\n\n如果上述不了解，可參考 [Docker 基本教學 - 從無到有 Docker-Beginners-Guide](https://github.com/twtrubiks/docker-tutorial)。\n\n來看一下 [requirements.txt](https://github.com/twtrubiks/django-translation-tutorial/blob/master/django_translation/requirements.txt)，這裡使用的是 `django==2.1.1`。\n\n之前我寫的 django 教學文章，可參考 [Django 基本教學 - 從無到有 Django-Beginners-Guide 📝](https://github.com/twtrubiks/django-tutorial)，不過要注意的是，\n\n這篇教學是 `django \u003c= 2.0`，django 2 有機會我會再寫篇文章介紹。\n\n由於 django 2 改動蠻大的，所以我在程式碼中，有些地方會增加註解，說明這段設定可以參考官網的哪部分文件。\n\n## 教學\n\n接下來就要教大家如何進行翻譯了，首先，先進入 [django_translation/settings.py](https://github.com/twtrubiks/django-translation-tutorial/blob/master/django_translation/django_translation/settings.py)，\n\n找到 MIDDLEWARE，並且加入 `django.middleware.locale.LocaleMiddleware`，這邊要注意擺放的位置，\n\n```python\nMIDDLEWARE = [\n    ...\n    'django.contrib.sessions.middleware.SessionMiddleware',\n\n    # https://docs.djangoproject.com/en/2.1/topics/i18n/translation/#how-django-discovers-language-preference\n    'django.middleware.locale.LocaleMiddleware',\n\n    'django.middleware.common.CommonMiddleware',\n    ...\n]\n```\n\n一定要放在 `django.contrib.sessions.middleware.SessionMiddleware` 之後，\n\n以及 `django.middleware.common.CommonMiddleware` 之前，原因如下，\n\n下方為官方說明，\n\n```text\nIt should come after SessionMiddleware, because LocaleMiddleware makes use of session\ndata. And it should come before CommonMiddleware because CommonMiddleware needs an\nactivated language in order to resolve the requested URL.\n```\n\n詳細的官方文件，可參考 [How Django discovers language preference](https://docs.djangoproject.com/en/2.1/topics/i18n/translation/#how-django-discovers-language-preference)。\n\n設定 LOCALE_PATHS， 可參考 [setting-LOCALE_PATHS](https://docs.djangoproject.com/en/2.1/ref/settings/#std:setting-LOCALE_PATHS)，\n\n在 [django_translation/settings.py](https://github.com/twtrubiks/django-translation-tutorial/blob/master/django_translation/django_translation/settings.py) 中增加以下 code，這資料夾到時候會擺放翻譯的 `django.po` 以及 `django.mo` 檔案。\n\n```python\nLOCALE_PATHS =  [\n    os.path.join(BASE_DIR, 'locale'),\n]\n```\n\n在 [django_translation/settings.py](https://github.com/twtrubiks/django-translation-tutorial/blob/master/django_translation/django_translation/settings.py) 中的 LANGUAGE_CODE 為預設的語言\n\n```python\nLANGUAGE_CODE = 'en-us'\n```\n\n如果你不知道國家的 LANGUAGE_CODE，可到 [language-identifiers.html](http://www.i18nguy.com/unicode/language-identifiers.html) 查詢各國家的 LANGUAGE_CODE\n。\n\n接著在 [django_translation/settings.py](https://github.com/twtrubiks/django-translation-tutorial/blob/master/django_translation/django_translation/settings.py) 中設定可以顯示的語言清單，增加下列 code，\n\n```python\nfrom django.utils.translation import gettext_lazy as _\nLANGUAGES = [\n    ('en-us', _('English')),\n    ('zh-hant', _('Traditional Chinese')),\n    ('zh-cn', _('Simplified Chinese')),\n]\n```\n\n`from django.utils.translation import gettext_lazy as _` 為翻譯，可參考 [standard-translation](https://docs.djangoproject.com/en/2.1/topics/i18n/translation/#standard-translation) ，\n\n然後非常建議大家在看一下 [lazy-translation](https://docs.djangoproject.com/en/2.1/topics/i18n/translation/#lazy-translation) 這篇，了解哪時候要使用 `gettext_lazy` 以及為什麼要使用\n\n`gettext_lazy`，通常是 defining models, forms and model forms 這些地方。\n\n更多詳細設定，可參考\n[How Django discovers language preference](https://docs.djangoproject.com/en/2.1/topics/i18n/translation/#how-django-discovers-language-preference)。\n\n[django_translation/settings.py](https://github.com/twtrubiks/django-translation-tutorial/blob/master/django_translation/django_translation/settings.py) 的設定到這邊就算告一個段落了:relaxed:\n\n接著設定 [django_translation/urls.py](https://github.com/twtrubiks/django-translation-tutorial/blob/master/django_translation/django_translation/urls.py) ，我們要增加 `path('i18n/', include('django.conf.urls.i18n'))`\n\n到 urlpatterns 中，這個主要目的是 Activate this view，\n\n以下為官方文件說明\n\n```text\nAs a convenience, Django comes with a view, django.views.i18n.set_language(), that sets\na user’s language preference and redirects to a given URL or, by default, back to the\nprevious page.\nActivate this view by adding the following line to your URLconf:\n```\n\n詳細可參考 [the-set-language-redirect-view](https://docs.djangoproject.com/en/2.1/topics/i18n/translation/#the-set-language-redirect-view)。\n\n```python\nurlpatterns = [\n    # https://docs.djangoproject.com/en/2.1/topics/i18n/translation/#the-set-language-redirect-view\n    path('i18n/', include('django.conf.urls.i18n')),\n    path('admin/', admin.site.urls),\n    path('tutorial/', include('tutorial.urls', namespace='tutorial' )),\n]\n```\n\n接著設定 [tutorial/urls.py](https://github.com/twtrubiks/django-translation-tutorial/blob/master/django_translation/tutorial/urls.py)，設定好了之後，來看 [tutorial/views.py](https://github.com/twtrubiks/django-translation-tutorial/blob/master/django_translation/tutorial/views.py)，\n\n讓我們來看在 view 中要怎麼實現翻譯， code 如下，\n\n```python\nfrom django.shortcuts import render\nfrom django.utils.translation import gettext as _\n\n# Create your views here.\ndef index(request):\n    data = _('Hello')\n\n    return render(request, 'tutorial/index.html', {\n        \"data\" : data\n    })\n```\n\n`_('Hello')` 這個就是翻譯。\n\n( 像這邊就是使用 `from django.utils.translation import gettext as _`，而不是 `gettext_lazy`。)\n\n有 view 之後，那接下來就是設定 [tutorial/templates/tutorial/index.html](https://github.com/twtrubiks/django-translation-tutorial/blob/master/django_translation/tutorial/templates/tutorial/index.html)。\n\n首先，我們先來設定可以切換語言的 select，可參考 [the-set-language-redirect-view](https://docs.djangoproject.com/en/2.1/topics/i18n/translation/#the-set-language-redirect-view)，\n\n以下為官方範例 code，\n\n```django\n{% load i18n %}\n\n\u003cform action=\"{% url 'set_language' %}\" method=\"post\"\u003e{% csrf_token %}\n    \u003cinput name=\"next\" type=\"hidden\" value=\"{{ redirect_to }}\"\u003e\n    \u003cselect name=\"language\"\u003e\n        {% get_current_language as LANGUAGE_CODE %}\n        {% get_available_languages as LANGUAGES %}\n        {% get_language_info_list for LANGUAGES as languages %}\n        {% for language in languages %}\n            \u003coption value=\"{{ language.code }}\"{% if language.code == LANGUAGE_CODE %} selected{% endif %}\u003e\n                {{ language.name_local }} ({{ language.code }})\n            \u003c/option\u003e\n        {% endfor %}\n    \u003c/select\u003e\n    \u003cinput type=\"submit\" value=\"Go\"\u003e\n\u003c/form\u003e\n```\n\n`{% load i18n %}` 很重要 ( 可參考 [internationalization-in-template-code](https://docs.djangoproject.com/en/2.1/topics/i18n/translation/#internationalization-in-template-code) 這邊的說明 )，記得要載入，\n\n我自己有簡單的使用 bootstrap3，可參考 [tutorial/templates/tutorial/index.html](https://github.com/twtrubiks/django-translation-tutorial/blob/master/django_translation/tutorial/templates/tutorial/index.html)，直接將翻譯文字顯示出來，\n\n如下方 code，\n\n```html\n\u003cdiv class=\"well well-sm\"\u003e{{data}}\u003c/div\u003e\n```\n\n到這邊，我們終於可以開始進行翻譯了:satisfied: ( 這邊我就只翻譯繁體，其他的以此類推 )。\n\n首先需要先執行 [makemessages](https://docs.djangoproject.com/en/2.1/ref/django-admin/#makemessages) 指令，建立出 `django.po` 檔案，指令如下，\n\n```cmd\ndjango-admin makemessages --locale=zh_Hant\n```\n\n這段 code ，會去 scan 你的 code ，將需要翻譯的找出來。 ( 例如 `_('Hello')` 就會被 scan 出來 )。\n\n![alt tag](https://i.imgur.com/X5FtFfc.png)\n\n注意，如果出現如下圖錯誤，\n\n![alt tag](https://i.imgur.com/HAdvlGe.png)\n\n```text\nCommandError: Can't find msguniq. Make sure you have GNU gettext tools 0.15 or newer installed.\n```\n\n這就是在 windows 上為什麼我用 docker 的原因，雖然網路上有人說 windows 可安裝 [gettext-iconv-windows](https://mlocati.github.io/articles/gettext-iconv-windows.html) 解決，\n\n但我一直遇到問題，最後果斷使用 docker:smiley:\n\n目錄中應該會有個 locale 的資料夾，因為我們在 LOCALE_PATHS 有設定，如果沒有請自行建立一個\n\n( 當 django run 起來的時候應該就會自己建立了 )。\n\n執行後會看到如下，產生了 zh_Hant 的 `django.po` 檔案，\n\n![alt tag](https://i.imgur.com/TMnsHaD.png)\n\n現在就是要對 `django.po` 進行翻譯，打開 `django.po`，你會發現 `'Hello'` 在裡面，\n\n![alt tag](https://i.imgur.com/tbCKEEI.png)\n\n將它翻譯後，再執行 compilemessages，可參考 [compilemessages](https://docs.djangoproject.com/en/2.1/ref/django-admin/#compilemessages)，指令如下\n\n```python\ndjango-admin compilemessages\n```\n\n![alt tag](https://i.imgur.com/Jk0TmrB.png)\n\n執行後，如果沒任何錯誤訊息，就是成功 compilemessages，`django.mo` 就是 compilemessages 過後的檔案。\n\n![alt tag](https://i.imgur.com/XrV9ah4.png)\n\n接著我們到網頁上觀看 [http://127.0.0.1:8000/tutorial/](http://127.0.0.1:8000/tutorial/)，\n\n英文\n\n![alt tag](https://i.imgur.com/NuMoW6k.png)\n\n中文\n\n![alt tag](https://i.imgur.com/UPhJnuK.png)\n\n我們也可以這樣寫，\n\n```python\nm=1\nd= 20\noutput = _('Today is %(month)s / %(day)s.') % {'month': m, 'day': d}\n```\n\n[django.po](https://github.com/twtrubiks/django-translation-tutorial/blob/master/django_translation/locale/zh_Hant/LC_MESSAGES/django.po) 如下，\n\n![alt tag](https://i.imgur.com/ihIlByc.png)\n\n這邊要提醒大家，假如你有做任何修改時，重新執行了 `django-admin makemessages --locale=zh_Hant` 時，\n\n你可能會看到像上圖 A 的部份，就是你修改之前的東西會幫你註解起來，我建議把這個都刪除，也就是 A 的部份。\n\n( 會請大家刪除的原因是，有時候它會導致你翻譯翻不出來，最後我是把那部份都刪除後，再執行  compilemessages 就正常了 )\n\n![alt tag](https://i.imgur.com/qI3tY3W.png)\n\n### contextual-markers\n\n什麼時候會用到它呢 ? 在英文翻中文常常會有這種況狀，就是一個英文的詞，在中文有很多意思的時候。\n\n舉個例子， blue 是 藍色 的意思，但 blue 也可以是 鬱悶 的意思，這時候，就需要使用 contextual-markers，\n\n參考以下 code ( 更多說明請參考 [contextual-markers](https://docs.djangoproject.com/en/2.1/topics/i18n/translation/#contextual-markers) )，code 在 [tutorial/views.py](https://github.com/twtrubiks/django-translation-tutorial/blob/master/django_translation/tutorial/views.py)，\n\n```python\n...\nfrom django.utils.translation import pgettext\n\n# Create your views here.\ndef index(request):\n    ...\n    # Translators: contextual-markers\n    p_blue_color = pgettext(\"color\", \"blue\")\n    # Translators: contextual-markers\n    p_blue_mood = pgettext(\"mood\", \"blue\")\n    ...\n    return render(request, 'tutorial/index.html', {\n        ...\n        \"p_blue_color\": p_blue_color,\n        \"p_blue_mood\": p_blue_mood,\n        ....\n    })\n```\n\n然後如果們執行 `django-admin makemessages --locale=zh_Hant`，你會發現 [django.po](https://github.com/twtrubiks/django-translation-tutorial/blob/master/django_translation/locale/zh_Hant/LC_MESSAGES/django.po) 如下，\n\n![alt tag](https://i.imgur.com/zvTbh4D.png)\n\n你會發現它被拆成兩個，將對應要翻譯的內容填進去就可以了。另外注意一下這個註解，也就是\n\n`# Translators: contextual-markers` 這個，如果你要在翻譯中註解，你可以在 python 中使用\n\n`# Translators` key 開頭，這樣 [django.po](https://github.com/twtrubiks/django-translation-tutorial/blob/master/django_translation/locale/zh_Hant/LC_MESSAGES/django.po) 就會有註解，更多詳細介紹可參考 [comments-for-translators](https://docs.djangoproject.com/en/2.1/topics/i18n/translation/#comments-for-translators)。\n\n翻譯完成後，再執行 compilemessages，\n\n如果是在 html 中想要使用 contextual-markers，則必須使用以下 code，\n\n```django\n{# contextual-markers #}\n\u003cdiv class=\"well well-sm\"\u003e{% trans \"blue\" context \"color\" %}\u003c/div\u003e\n\u003cdiv class=\"well well-sm\"\u003e{% trans \"blue\" context \"mood\" %}\u003c/div\u003e\n```\n\n![alt tag](https://i.imgur.com/viDCMKi.png)\n\n### pluralization\n\n有時候我們會有單數和複數顯示不同的需求，這時候就可以使用\n[pluralization](https://docs.djangoproject.com/en/2.1/topics/i18n/translation/#pluralization)，官方說明如下\n\n```text\nngettext() takes three arguments: the singular translation string, the plural translation\nstring and the number of objects.\n```\n\n範例 code，code 在 [tutorial/views.py](https://github.com/twtrubiks/django-translation-tutorial/blob/master/django_translation/tutorial/views.py)，\n\n```python\nfrom django.utils.translation import ngettext\n# pluralization\ncount = 2\npluralization = ngettext(\n'There is %(count)d %(name)s object available.',\n'There are %(count)d %(name)s objects available.',\ncount\n) % {\n    'count': count,\n    'name':'test',\n}\n```\n\n執行 makemessages，\n\n![alt tag](https://i.imgur.com/AfoqZlv.png)\n\n在 html 中，\n\n```html\n{# pluralization #}\n\u003cdiv class=\"well well-sm\"\u003e{{pluralization}}\u003c/div\u003e\n```\n\n![alt tag](https://i.imgur.com/naaDKpt.png)\n\n你可以把 count 改成 `count = 1`，這樣就會變成單數了。\n\n### Internationalization: in template code\n\n接著來看在 template 中要如何進行翻譯，請參考 [tutorial/templates/tutorial/index.html](https://github.com/twtrubiks/django-translation-tutorial/blob/master/django_translation/tutorial/templates/tutorial/index.html)，\n\n```django\n{% load i18n %}\n\n{% comment %}Translators: Hello Django{% endcomment %}\n\u003cdiv class=\"well well-sm\"\u003e{% trans \"Hello Django\" %}\u003c/div\u003e\n\n{# Translators: comment #}\n\u003cdiv class=\"well well-sm\"\u003e{% trans \"comment\" %}\u003c/div\u003e\n```\n\n上面提供了兩種的註解方式，詳細可參考 [comments-for-translators-in-templates](https://docs.djangoproject.com/en/2.1/topics/i18n/translation/#comments-for-translators-in-templates)。\n\n`{% load i18n %}` 記得要載入，\n\n接著執行 `django-admin makemessages --locale=zh_Hant` 產生  [django.po](https://github.com/twtrubiks/django-translation-tutorial/blob/master/django_translation/locale/zh_Hant/LC_MESSAGES/django.po) 檔案\n\n![alt tag](https://i.imgur.com/D8Hj7RG.png)\n\n註解也會產生在你的  [django.po](https://github.com/twtrubiks/django-translation-tutorial/blob/master/django_translation/locale/zh_Hant/LC_MESSAGES/django.po) 中，最後 compilemessages，\n\n![alt tag](https://i.imgur.com/pGmmMaa.png)\n\n另外還有一種是設定為變數，方法如下\n\n```django\n{# Translators: var #}\n{% trans \"This is the title\" as the_title %}\n\u003cdiv class=\"well well-sm\"\u003e{{ the_title }}\u003c/div\u003e\n```\n\n剩下的部分和剛剛都一樣，這邊我就不再做一遍了。\n\n接下來是可能有一種情況，例如，英文是顯示 `show Hello`，而中文要顯示 `哈摟顯示`，\n\n這時候，我們就不能使用之前的 `{% trans \"This is the title\" %}` 的方法，因為中英的位置\n\n不一樣，這時候，就必須使用 `Translators: \"{% blocktrans %}....{% endblocktrans %}` 的方式，\n\n下列為變數的方法，寫法有兩種，code 請參考 [tutorial/templates/tutorial/index.html](https://github.com/twtrubiks/django-translation-tutorial/blob/master/django_translation/tutorial/templates/tutorial/index.html)，\n\n```django\n{# Translators: \"{% blocktrans %}....{% endblocktrans %} #}\n\u003cdiv class=\"well well-sm\"\u003e{%blocktrans with d=data %}show {{d}}{%endblocktrans%}\u003c/div\u003e\n\u003cdiv class=\"well well-sm\"\u003e{%blocktrans with data as d %}show {{d}}{%endblocktrans%}\u003c/div\u003e\n```\n\n接著執行 `django-admin makemessages --locale=zh_Hant` 產生  [django.po](https://github.com/twtrubiks/django-translation-tutorial/blob/master/django_translation/locale/zh_Hant/LC_MESSAGES/django.po) 檔案，\n\n![alt tag](https://i.imgur.com/1LpeUEk.png)\n\n剩下的步驟這邊就省略了:relaxed:前面都說很多次了。\n\n再來說一下 `trimmed option`，\n\n有時候，我們希望經過 `django-admin makemessages --locale=zh_Hant` 產生  [django.po](https://github.com/twtrubiks/django-translation-tutorial/blob/master/django_translation/locale/zh_Hant/LC_MESSAGES/django.po) 的檔案不要有換行\n\n字元 `\\n` 這類的，這時候，就可以使用  trimmed 這個 option。\n\n( 有時候 `\\n` 這類的字元甚至會導致翻譯錯誤，所以建議能加 trimmed 就加吧 )\n\n```django\n{% blocktrans trimmed %}\nFirst sentence.\nSecond sentence.\n{% endblocktrans %}\n```\n\n再來說一下另一個 `noop option`，官方說明如下，\n\n```text\nIf the noop option is present, variable lookup still takes place but the translation is\nskipped. This is useful when “stubbing out” content that will require translation in\nthe future:\n```\n\n如果加上這個 `noop option`，它將不會被翻譯，經過 `django-admin makemessages --locale=zh_Hant`\n\n產生  [django.po](https://github.com/twtrubiks/django-translation-tutorial/blob/master/django_translation/locale/zh_Hant/LC_MESSAGES/django.po) 的檔案中，還是會有翻譯的內容，但不會被翻譯出來( skipped )，也就是說，可以使用在未來\n\n會翻譯，但目前還不需要的情境下，\n\n```django\n{# Translators: noop #}\n\u003cdiv class=\"well well-sm\"\u003e{% trans \"myvar\" noop  %}\u003c/div\u003e\n```\n\n### Internationalization: in JavaScript code\n\n* [Youtube Tutorial PART 3 - django-translation-tutorial](https://youtu.be/9njecageJvM)\n\n一定會有人問，那如果我是透過 javascript ，有辦法進行翻譯嗎:question:\n\n是可以的:satisfied:這邊就來教大家如何設定，\n\n先到 [django_translation/urls.py](https://github.com/twtrubiks/django-translation-tutorial/blob/master/django_translation/django_translation/urls.py) 設定 [The JavaScriptCatalog view](https://docs.djangoproject.com/en/2.1/topics/i18n/translation/#module-django.views.i18n)，\n\n```python\nfrom django.views.i18n import JavaScriptCatalog\n\nurlpatterns = [\n    ....\n    #https://docs.djangoproject.com/en/2.1/topics/i18n/translation/#module-django.views.i18n\n    path('jsi18n/', JavaScriptCatalog.as_view(), name='javascript-catalog'),\n    ...\n]\n```\n\n接著在 [tutorial/templates/tutorial/index.html](https://github.com/twtrubiks/django-translation-tutorial/blob/master/django_translation/tutorial/templates/tutorial/index.html) 中新增以下 code，\n\n```django\n{# Using the JavaScript translation catalog #}\n{# https://docs.djangoproject.com/en/2.1/topics/i18n/translation/#using-the-javascript-translation-catalog #}\n\u003cscript type=\"text/javascript\" src=\"{% url 'javascript-catalog' %}\"\u003e\u003c/script\u003e\n```\n\n更多詳細介紹可參考官方文件 [using-the-javascript-translation-catalog](https://docs.djangoproject.com/en/2.1/topics/i18n/translation/#using-the-javascript-translation-catalog)。\n\n接下來請注意，請 **新增一個 js 檔案** ，不能直接將 js 寫在 [tutorial/templates/tutorial/index.html](https://github.com/twtrubiks/django-translation-tutorial/blob/master/django_translation/tutorial/templates/tutorial/index.html)  中，\n\n會抓不到，所以我們新增一個 [tutorial/static/js/index.js](https://github.com/twtrubiks/django-translation-tutorial/blob/master/django_translation/tutorial/static/js/index.js) 檔案，並且在裡面填入以下 code，\n\n使用方法也很簡單，和在 python 翻譯的時候差不多，考以直接使用 [gettext](https://docs.djangoproject.com/en/2.1/topics/i18n/translation/#gettext)，\n\n```javascript\nvar data = gettext('this is to be translated')\ndocument.write( '\u003cdiv class=\"well well-sm\"\u003e'+ data + '\u003c/div\u003e');\n```\n\n之後再回到 [tutorial/templates/tutorial/index.html](https://github.com/twtrubiks/django-translation-tutorial/blob/master/django_translation/tutorial/templates/tutorial/index.html) 中 import 它，\n\n```django\n{% load static %}\n\u003cscript type=\"text/javascript\" src=\"{% static \"tutorial/index.js\" %}\"\u003e\u003c/script\u003e\n```\n\n接著我們要建立 [djangojs.po](https://github.com/twtrubiks/django-translation-tutorial/blob/master/django_translation/locale/zh_Hant/LC_MESSAGES/djangojs.po)，指令有點不一樣，\n\n```python\ndjango-admin makemessages -d djangojs -l zh_Hant\n```\n\n![alt tag](https://i.imgur.com/NAN8l3r.png)\n\n執行後你會發現多出 [djangojs.po](https://github.com/twtrubiks/django-translation-tutorial/blob/master/django_translation/locale/zh_Hant/LC_MESSAGES/djangojs.po)，\n\n![alt tag](https://i.imgur.com/nsgq8n8.png)\n\n[djangojs.po](https://github.com/twtrubiks/django-translation-tutorial/blob/master/django_translation/locale/zh_Hant/LC_MESSAGES/djangojs.po) 的內容如下，這邊我們成功的抓到 js 裡面的翻譯，\n\n![alt tag](https://i.imgur.com/BOAjA15.png)\n\n更多詳細可參考 [Creating message files from JavaScript source code](https://docs.djangoproject.com/en/2.1/topics/i18n/translation/#creating-message-files-from-javascript-source-code)，\n\n接著執行 compilemessages，指令則是一樣的，`django-admin compilemessages`\n\n![alt tag](https://i.imgur.com/bs2L6Pc.png)\n\n最後再到網頁上觀看 [http://127.0.0.1:8000/tutorial/](http://127.0.0.1:8000/tutorial/)，js 也成功翻譯了:smiley:\n\n![alt tag](https://i.imgur.com/QbXvtuT.png)\n\n## 後記：\n\n這次一不小心寫了好多，很多地方基本上我都有在 code 的部分放上註解以及官方的參考網址，\n\n整體來說，我覺得 [django-translation](https://docs.djangoproject.com/en/2.1/topics/i18n/translation/) 蠻完善的，連 js 也整合了進來，這次就介紹到這邊，謝謝大家:heart_eyes:\n\n## 執行環境\n\n* Python 3.6.2\n* windows 10\n\n## Reference\n\n* [django-translation](https://docs.djangoproject.com/en/2.1/topics/i18n/translation/)\n\n* [django-bootstrap3](https://github.com/dyve/django-bootstrap3)\n\n## Donation\n\n文章都是我自己研究內化後原創，如果有幫助到您，也想鼓勵我的話，歡迎請我喝一杯咖啡:laughing:\n\n![alt tag](https://i.imgur.com/LRct9xa.png)\n\n[贊助者付款](https://payment.opay.tw/Broadcaster/Donate/9E47FDEF85ABE383A0F5FC6A218606F8)\n\n## License\n\nMIT license\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftwtrubiks%2Fdjango-translation-tutorial","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftwtrubiks%2Fdjango-translation-tutorial","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftwtrubiks%2Fdjango-translation-tutorial/lists"}