{"action":"created","issue":{"url":"https://api.github.com/repos/zewa666/aurelia-i18next/issues/11","labels_url":"https://api.github.com/repos/zewa666/aurelia-i18next/issues/11/labels{/name}","comments_url":"https://api.github.com/repos/zewa666/aurelia-i18next/issues/11/comments","events_url":"https://api.github.com/repos/zewa666/aurelia-i18next/issues/11/events","html_url":"https://github.com/zewa666/aurelia-i18next/issues/11","id":73620446,"number":11,"title":"Use attributes to manage translations","user":{"login":"wichert","id":199657,"avatar_url":"https://avatars.githubusercontent.com/u/199657?v=3","gravatar_id":"","url":"https://api.github.com/users/wichert","html_url":"https://github.com/wichert","followers_url":"https://api.github.com/users/wichert/followers","following_url":"https://api.github.com/users/wichert/following{/other_user}","gists_url":"https://api.github.com/users/wichert/gists{/gist_id}","starred_url":"https://api.github.com/users/wichert/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/wichert/subscriptions","organizations_url":"https://api.github.com/users/wichert/orgs","repos_url":"https://api.github.com/users/wichert/repos","events_url":"https://api.github.com/users/wichert/events{/privacy}","received_events_url":"https://api.github.com/users/wichert/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":4,"created_at":"2015-05-06T13:29:05Z","updated_at":"2015-05-21T09:24:43Z","closed_at":null,"body":"The current way to do translations with aurelia-i18n looks like this:\r\n\r\n```html\r\n<p>${ 'message' | t}</p>\r\n```\r\n\r\nYou then need to run a tool like [i18next-parser](https://github.com/i18next/i18next-parser) over your templates to produce a JSON file, enter the canonical text in there and then pass that on to translators. There are several things I personally do not like about this approach:\r\n\r\n* It requires you to always change two files when adding or removing texts.\r\n* Not seeing the canonical text in the templates makes it harder to reorganise/modify templates - I always need to look in two places to see how a text is used, or edit in two places if I change the semantics and position of a text.\r\n* It requires having to define a unique keyword for every text. This is needless extra work, and can lead to the same text appearing in multiple locations while using a different identifier. In my experience using an identifier also leads to problems with existing translation software: many translators can not deal with files where the identifier for a text is not the text itself, and some will only show the identifier to the user. As a translator being asked to translate `header_intro_welcome` without any extra context is quite difficult.\r\n* It uses a very non-standard magic naming to insert variables `__variable__` instead of a more common syntax like `${variable}` or just `$variable`\r\n* It does not seem to allow nested elements in a translated context. For example translating something like `<p>Hello <em>${name}</em></p>`. It is not uncommon to have translations that are nested 2 (and sometimes even 3) levels deep.\r\n\r\nAn alternative approach to managing translations in a HTML context is to use attributes to mark elements as translatable. One way of doing this is the [zope.i18n](https://chameleon.readthedocs.org/en/latest/reference.html#translation-i18n) syntax. I made a [quick gist](https://gist.github.com/wichert/11f815107f11af3e8fc3) which shows what this looks like. A few notes about this example:\r\n\r\n* line 2 shows the the simplest example: it uses the text of the `h1` element itself as identifier.\r\n* line 3 shows the use of an element inside a translation. The `span` is marked with an `i18n:name` attribute which is used in place of the element in the text seen by translators, as you can see on line 26 of the POT file. This allows the translator to move the span around in the translation as needed.\r\n* Sometimes you have the exact same text in multiple places but with slightly different semantics, requiring different translations in other languages. This can be handled by specyfing a _context_ for a message. You can see an example of this line 4.\r\n* line 8 shows how you can still specify an explicit identifier by providing a value for the `i18n:translate` attribute. An extraction tool will normally add the canonical text as a comment to the message, as you can see on line 35 of the POT file.\r\n\r\nThe zope.i18n approach works quite well. I won't argue that it is perfect, there is certainly some room for improvement: \r\n\r\n* Having to add an `i18n:translate` attribute to every element can become a bit repetitive. [Genshi](http://genshi.edgewall.org/wiki/Documentation/0.6.x/i18n.html#messages) experimented with an alternative syntax and implicitly making all text translatable. I'm not entirely convinced that approach is better, but it is certainly interesting.\r\n* There is no support for plural handling in the syntax. This might be easy to add. Amazingly in 10 years of using zope.i18n syntax I haven't needed to do that, but it is certainly a desirable feature to have.\r\n\r\n[Obviel](http://www.obviel.org/en/latest/template_i18n.html) has an implementation of a zope.i18n-inspired syntax that is also interesting to look at."},"comment":{"url":"https://api.github.com/repos/zewa666/aurelia-i18next/issues/comments/104193476","html_url":"https://github.com/zewa666/aurelia-i18next/issues/11#issuecomment-104193476","issue_url":"https://api.github.com/repos/zewa666/aurelia-i18next/issues/11","id":104193476,"user":{"login":"wichert","id":199657,"avatar_url":"https://avatars.githubusercontent.com/u/199657?v=3","gravatar_id":"","url":"https://api.github.com/users/wichert","html_url":"https://github.com/wichert","followers_url":"https://api.github.com/users/wichert/followers","following_url":"https://api.github.com/users/wichert/following{/other_user}","gists_url":"https://api.github.com/users/wichert/gists{/gist_id}","starred_url":"https://api.github.com/users/wichert/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/wichert/subscriptions","organizations_url":"https://api.github.com/users/wichert/orgs","repos_url":"https://api.github.com/users/wichert/repos","events_url":"https://api.github.com/users/wichert/events{/privacy}","received_events_url":"https://api.github.com/users/wichert/received_events","type":"User","site_admin":false},"created_at":"2015-05-21T09:24:43Z","updated_at":"2015-05-21T09:24:43Z","body":"I’m fighting a few deadlines today, but I’ll definitely look at this ticket and your work again over the weekend!\n\n"}}