{"id":239,"date":"2012-02-09T12:25:03","date_gmt":"2012-02-09T09:25:03","guid":{"rendered":"http:\/\/laxstrom.name\/blag\/?p=239"},"modified":"2012-02-09T12:25:03","modified_gmt":"2012-02-09T09:25:03","slug":"new-translation-memories-near-you-soon","status":"publish","type":"post","link":"https:\/\/laxstrom.name\/blag\/2012\/02\/09\/new-translation-memories-near-you-soon\/","title":{"rendered":"New translation memories near you soon"},"content":{"rendered":"<p id=\"magicdomid79\">In the last sprint I developed a translation memory server in PHP almost from scratch. Well, it&#8217;s not really a server. It&#8217;s run inside <a href=\"https:\/\/www.mediawiki.org \">MediaWiki<\/a>\u00a0during client requests. It closely follows the logic of <a href=\"http:\/\/translate.sourceforge.net\/wiki\/toolkit\/tmserver\">tmserver<\/a> from <a href=\"https:\/\/en.wikipedia.org\/wiki\/Translate_Toolkit\">translatetoolkit<\/a>, which uses Python and SQLite.<\/p>\n<p id=\"magicdomid81\">The logic of how it works is pretty simple:\u00a0you store all definitions and translations in a database. Then you can query suggestions for a certain text. We use string length and fulltext search to filter the initial list of candidate messages down. After that we use a text similarity algorithm\u00a0to rank the suggestions and do the final filtering. The logic is explained in more detail in the <a href=\"https:\/\/www.mediawiki.org\/wiki\/Help:Extension:Translate\/Translation_memories\">Translate extension help<\/a>.<\/p>\n<p id=\"magicdomid83\">PHP provides a text matching function, but we (<a href=\"https:\/\/www.mediawiki.org\/wiki\/User:Santhosh.thottingal\">Santhosh<\/a>) had to implement pure PHP fallback for strings longer than 255 bytes or strings containing anything else than ASCII. The pure PHP version is much slower, although that is offset a little because it&#8217;s more efficient when there are fewer characters in a string than bytes. But more importantly, it works correctly even when not handling English text. The faster implementation is used when possible. Before we did some optimizations to the matching process, it was the slowest part. After those optimizations the time is now bound by database access. The functions implement the <a href=\"https:\/\/en.wikipedia.org\/wiki\/Levenshtein_distance\">Levenshtein edit distance algorithm<\/a>.<\/p>\n<p id=\"magicdomid85\">End users won&#8217;t see much difference. Wanting a translation memory on Wikimedia wikis was the original reason for reimplementing translation memory in PHP, and in the coming sprints we are going to enable it on wikis where Translate is enabled (<a href=\"https:\/\/meta.wikimedia.org\/wiki\/Special:Translate\">meta-wiki<\/a>, <a href=\"https:\/\/www.mediawiki.org\/wiki\/Special:Translate\">mediawiki.org<\/a>, <a href=\"https:\/\/incubator.wikimedia.org\/wiki\/Special:Translate\">incubator<\/a> and <a href=\"https:\/\/wikimania2012.wikimedia.org\/wiki\/Special:Translate\">wikimania2012<\/a> currently). It is just over 300 lines of code [<a title=\"Code of TTMServer\" href=\"http:\/\/svn.wikimedia.org\/viewvc\/mediawiki\/trunk\/extensions\/Translate\/utils\/TTMServer.php?view=markup\">1<\/a>] including comments and in addition there are database table definitions [<a title=\"TTMServer database tables\" href=\"http:\/\/svn.wikimedia.org\/viewvc\/mediawiki\/trunk\/extensions\/Translate\/sql\/translate_tm.sql?view=markup\">2<\/a>].<\/p>\n<p id=\"magicdomid87\">Now,\u00a0having explained what was done and why, I can reveal the cool stuff, if you are still reading. There will also be a <a href=\"https:\/\/www.mediawiki.org\/wiki\/API:Main_page\">MediaWiki API<\/a> module that allows querying the translation memory. There is a simple switch in the configuration to choose whether the memory is public or private. In the future this will allow querying translation memories from other sites, too.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In the last sprint I developed a translation memory server in PHP almost from scratch. Well, it&#8217;s not really a server. It&#8217;s run inside MediaWiki\u00a0during client requests. It closely follows the logic of tmserver from translatetoolkit, which uses Python and SQLite. The logic of how it works is pretty simple:\u00a0you store all definitions and translations [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[3,10,2,9,11],"tags":[],"class_list":["post-239","post","type-post","status-publish","format-standard","hentry","category-english","category-kde","category-mediawiki","category-translatewiki-net","category-vapaasuomi"],"_links":{"self":[{"href":"https:\/\/laxstrom.name\/blag\/wp-json\/wp\/v2\/posts\/239","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/laxstrom.name\/blag\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/laxstrom.name\/blag\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/laxstrom.name\/blag\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/laxstrom.name\/blag\/wp-json\/wp\/v2\/comments?post=239"}],"version-history":[{"count":9,"href":"https:\/\/laxstrom.name\/blag\/wp-json\/wp\/v2\/posts\/239\/revisions"}],"predecessor-version":[{"id":249,"href":"https:\/\/laxstrom.name\/blag\/wp-json\/wp\/v2\/posts\/239\/revisions\/249"}],"wp:attachment":[{"href":"https:\/\/laxstrom.name\/blag\/wp-json\/wp\/v2\/media?parent=239"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/laxstrom.name\/blag\/wp-json\/wp\/v2\/categories?post=239"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/laxstrom.name\/blag\/wp-json\/wp\/v2\/tags?post=239"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}