{"action":"created","issue":{"url":"https://api.github.com/repos/TryGhost/Ghost/issues/8437","repository_url":"https://api.github.com/repos/TryGhost/Ghost","labels_url":"https://api.github.com/repos/TryGhost/Ghost/issues/8437/labels{/name}","comments_url":"https://api.github.com/repos/TryGhost/Ghost/issues/8437/comments","events_url":"https://api.github.com/repos/TryGhost/Ghost/issues/8437/events","html_url":"https://github.com/TryGhost/Ghost/pull/8437","id":225851753,"number":8437,"title":"[i18n] Translatable Ghost's frontend: Themes, dates, pagination, subscribe forms","user":{"login":"juan-g","id":3011323,"avatar_url":"https://avatars2.githubusercontent.com/u/3011323?v=3","gravatar_id":"","url":"https://api.github.com/users/juan-g","html_url":"https://github.com/juan-g","followers_url":"https://api.github.com/users/juan-g/followers","following_url":"https://api.github.com/users/juan-g/following{/other_user}","gists_url":"https://api.github.com/users/juan-g/gists{/gist_id}","starred_url":"https://api.github.com/users/juan-g/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/juan-g/subscriptions","organizations_url":"https://api.github.com/users/juan-g/orgs","repos_url":"https://api.github.com/users/juan-g/repos","events_url":"https://api.github.com/users/juan-g/events{/privacy}","received_events_url":"https://api.github.com/users/juan-g/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":{"login":"ErisDS","id":101513,"avatar_url":"https://avatars2.githubusercontent.com/u/101513?v=3","gravatar_id":"","url":"https://api.github.com/users/ErisDS","html_url":"https://github.com/ErisDS","followers_url":"https://api.github.com/users/ErisDS/followers","following_url":"https://api.github.com/users/ErisDS/following{/other_user}","gists_url":"https://api.github.com/users/ErisDS/gists{/gist_id}","starred_url":"https://api.github.com/users/ErisDS/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ErisDS/subscriptions","organizations_url":"https://api.github.com/users/ErisDS/orgs","repos_url":"https://api.github.com/users/ErisDS/repos","events_url":"https://api.github.com/users/ErisDS/events{/privacy}","received_events_url":"https://api.github.com/users/ErisDS/received_events","type":"User","site_admin":false},"assignees":[{"login":"ErisDS","id":101513,"avatar_url":"https://avatars2.githubusercontent.com/u/101513?v=3","gravatar_id":"","url":"https://api.github.com/users/ErisDS","html_url":"https://github.com/ErisDS","followers_url":"https://api.github.com/users/ErisDS/followers","following_url":"https://api.github.com/users/ErisDS/following{/other_user}","gists_url":"https://api.github.com/users/ErisDS/gists{/gist_id}","starred_url":"https://api.github.com/users/ErisDS/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ErisDS/subscriptions","organizations_url":"https://api.github.com/users/ErisDS/orgs","repos_url":"https://api.github.com/users/ErisDS/repos","events_url":"https://api.github.com/users/ErisDS/events{/privacy}","received_events_url":"https://api.github.com/users/ErisDS/received_events","type":"User","site_admin":false}],"milestone":null,"comments":7,"created_at":"2017-05-02T23:41:27Z","updated_at":"2017-05-05T10:45:27Z","closed_at":null,"pull_request":{"url":"https://api.github.com/repos/TryGhost/Ghost/pulls/8437","html_url":"https://github.com/TryGhost/Ghost/pull/8437","diff_url":"https://github.com/TryGhost/Ghost/pull/8437.diff","patch_url":"https://github.com/TryGhost/Ghost/pull/8437.patch"},"body":"no issue\r\n\r\n- (note: this Ghost commit is completed by a Casper commit: _\"[i18n] Translatable Casper default theme\"_)\r\n\r\n- complete automatic translation of Ghost's frontend for site visitors (themes, etc.), to quickly deploy a site in a non-English language\r\n- when the translation files are in place (Spanish full frontend now available for a start), frontend language is switched by just changing the default English locale \"en\" (e.g.: currentLocale = 'es',) in file core/server/i18n.js; this could be done in settings instead of file in future enhancements; the corresponding translation file (en.json, es.json...) should be at core/server/translations/\r\n- comprehensively tested and fully working, with minimum and careful code changes, maintaining the original behavior of the default English version\r\n- dates with automatically translatable month names via moment.locale() in file core/server/helpers/date.js, since Ghost was already using Moment.js, which currently includes a large number of languages for Node.js without need for additional files; see:\r\n  http://momentjs.com/docs/#/i18n/\r\n  https://github.com/moment/moment/tree/develop/locale\r\n- all 29 frontend text strings (theme, pagination, subscribe email forms) replaced by translatable handlebars expressions, created like already existing handlebars helpers, etc. in file core/server/helpers/index.js\r\n- current English text strings for themes now without modification at the end of already existing file core/server/translations/en.json\r\n- added file core/server/translations/es.json with Spanish translations for all frontend text strings for site visitors; the backend for admins is still in English\r\n- core/server/helpers/tpl/pagination.hbs (outside of themes but used by them), with also now automatically translatable pagination\r\n- the subscribe email forms that are now translatable are those available by enabling the Subscribers feature in Labs settings; see .hbs and .js files in core/server/apps/subscribers, core/server/helpers, and the theme\r\n- core/server/helpers/plural.js is now ready for flexible translations with replacement\r\n- compatibility with both old themes and i18n-capable themes\r\n- locale (e.g. \"en\") now exported from core/server/i18n.js to make it available for other files when needed, using the Ghost standard core/server/helpers/proxy.js; now locale used in this way in two files, core/server/helpers/index.js and core/server/helpers/date.js\r\n- best two next enhancements would be language selection in settings instead of file, and using Transifex for volunteer automated translations of the *.json language files instead of editing them by hand; see:\r\n  https://docs.transifex.com/projects/updating-content\r\n  https://docs.transifex.com/formats/json\r\n- translatable themes are also a necessary basis for future enhancements such as multi-language sites with content in several languages instead of one non-English language\r\n"},"comment":{"url":"https://api.github.com/repos/TryGhost/Ghost/issues/comments/299434801","html_url":"https://github.com/TryGhost/Ghost/pull/8437#issuecomment-299434801","issue_url":"https://api.github.com/repos/TryGhost/Ghost/issues/8437","id":299434801,"user":{"login":"juan-g","id":3011323,"avatar_url":"https://avatars2.githubusercontent.com/u/3011323?v=3","gravatar_id":"","url":"https://api.github.com/users/juan-g","html_url":"https://github.com/juan-g","followers_url":"https://api.github.com/users/juan-g/followers","following_url":"https://api.github.com/users/juan-g/following{/other_user}","gists_url":"https://api.github.com/users/juan-g/gists{/gist_id}","starred_url":"https://api.github.com/users/juan-g/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/juan-g/subscriptions","organizations_url":"https://api.github.com/users/juan-g/orgs","repos_url":"https://api.github.com/users/juan-g/repos","events_url":"https://api.github.com/users/juan-g/events{/privacy}","received_events_url":"https://api.github.com/users/juan-g/received_events","type":"User","site_admin":false},"created_at":"2017-05-05T10:45:27Z","updated_at":"2017-05-05T10:45:27Z","body":"@ErisDS, thank you for your kind and detailed message. Later I will be able to answer your really interesting points, with my personal views about possible improvements, etc.\r\n\r\nFor now, I've just amended the two commits and corresponding pull requests (for Ghost and Casper), to use just one `{{t}}` helper for all frontend/theme translations, apart from another` {{i18nCss}}` helper for a few css content translations. The new `{{t}}` helper inherits the functionality of Ghost's `i18n.t` translation function, which was already in use by the backend.\r\n\r\nIt seems to be working all well. Of course, the automated Travis CI checks are still complaining about those unexpected two new helpers: \r\n\r\n> Helpers Load Core Helpers should have exactly the right helpers:\r\n> AssertionError: expected Array [ 't', 'i18nCss' ] to have property length of 0 (got 2)\r\n\r\nBut as the old proverb says, _\"the person who says it can't be done should not interrupt the person doing it\"_. OK, Travis CI is a test, not a person. ;)\r\n\r\nUsage examples in templates:\r\n```\r\n{{t \"frontend.olderPosts\"}}\r\n{{{t \"frontend.proudlyPublishedWith\" ghostLink=\"<a href=\\\"https://ghost.org\\\">Ghost</a>\"}}}\r\n```\r\nAnd, in core/server/translations/en.json:\r\n```\r\n{\r\n    \"frontend\": {\r\n        \"olderPosts\": \"Older Posts\",\r\n        \"proudlyPublishedWith\": \"Proudly published with {ghostLink}\"\r\n    }\r\n}\r\n```"}}
{"actor":{"display_login":"juan-g"}}