Extension:GoogleTranslate

From MediaWiki.org
Jump to: navigation, search

Script error

MediaWiki extensions manual
Crystal Clear action run.png
GoogleTranslate

Release status: beta

GoogleTranslateDK.jpg
Implementation Google (invalid type), Ajax
Description Ajax bar to Google Translate
Author(s) Per Feldvoss Olsen (credits to Adam Meyer!) (Assettalk)
Latest version 0.999
MediaWiki >=1.12
License I give up all rights. You may do what you please with this code.
Download Download
updated with a version that actually works!
Example http:// na
Hooks used
AlternateEdit

Translate the GoogleTranslate extension if it is available at translatewiki.net

Check usage and version matrix; code metrics

A translation function calling GoogleTranslate AJAX API - based upon code from Extension:Link_Suggest

This extension will allow you to directly translate the text that you edit! This is done by calling Googles AJAX API.

Warning: The code works in Firefox, Opera and Chrome. But it does not work for IE (Internet explorer). When running in IE, the current code removes linebreaks. I will look into this problem ASAP.


Improvements[edit | edit source]

Please could someone look into how to make this work in conjunction to say Template:Languages/Lang Extension:Duplicator etc.

Installing the code[edit | edit source]

You need to cut, edit and save the following code snips, in /extensions/GoogleTranslate/, using these names:

  • GoogleTranslate.php
  • GoogleTranslate.js
  • GoogleTranslate.css

Correct these lines, to reflect your language, in the js code: // Change to your language specific texts - this should be a global in localsettings though!!

var from_to_text = "Oversæt fra/til: ";                 // " Trasnlate from/to: "
var translate_text = " klik her for at oversætte nu ";  // " click here to translate "       
var close_text = " ( luk oversætter værktøjet. ) ";     // " ( close translate tool ) "  

This button is needed Template button translate.png - or rather you need to edit it to give the correct text for your language! So save the button, edit it, and give it a language specific name and change the code that loads the toolbar - this looks like:

add_image.src="skins/common/images/button_translate_da.png"; // you may like to put this somewhere else say in images\ ?

Please upload the button and add it below to the list of buttons!


Add this line to the localsettings.php:

require_once("$IP/extensions/GoogleTranslate/GoogleTranslate.php");

Buttons[edit | edit source]

Once you have created a button for your language, please add it here:

  • Danish/Dansk: Button translate da.png - reads "Translate text", save and copy to your 'skins\common\images' directory
  • Template button: Button translate temp.png - for you to download

Usage[edit | edit source]

Once installed you activate Edit on some page you want to work with. You will now see a new blank button appear: Template button translate.png - please change this to fit your language, see below!

When you click the new button you will see something like this above your edit-text:

GoogleTranslateDK.jpg

You need to change the from/to texts to read say 'ge'/'en' to translate from german to english. Also you can change the preferred translation languages in the JS code......

Put the cursor over the text that reads something like "click to translate now" and the translation will happen. (for longer texts, more sentences you will see the text flicker a bit.)

Code[edit | edit source]

PHP[edit | edit source]

This is where the GoogleApi is actually loaded....

<?php
/**
 * GoogleTranslate extension
 * @author Per Feldvoss Olsen (based on code by Adam Meyer)
 * @copyright © 2008 Per Feldvoss Olsen 
 */
 
//See below under "function wfAjaxGoogleTranslate" for configuration
 
if( !defined( 'MEDIAWIKI' ) ) {
        echo( "This file is part of an extension to the MediaWiki software and cannot be used standalone.\n" );
        die( 1 );
}
 
$wgExtensionFunctions[] = 'wfAjaxtranslate';
$wgAjaxExportList[] = 'wfAjaxGoogleTranslate';
$wgHooks['AlternateEdit'][] = 'wfAjaxGoogleTranslateHeaders';
 
$wgExtensionCredits['other'][] = array(
    'name'=> 'GoogleTranslate',
    'author'=> 'Per Feldvoss Olsen',
    'version'=> '0.2',
    'url' => 'http://www.mediawiki.org/wiki/Extension:GoogleTranslate',
    'description'=> 'Ajax-based link translation that translates edittext from/to via GoogleTranslate'
);
 
function wfAjaxtranslate() {
        global $wgUseAjax, $wgOut, $wgTitle;
        if (!$wgUseAjax) {
                wfDebug('wfAjaxtranslate: $wgUseAjax is not enabled, aborting extension setup.');
                return;
        }
}
 
function wfAjaxGoogleTranslate( $term ) {
 
        //configure the following to change settings
        $limit = 8; //number of results to spit back
        $location = 1; //set to 1 to search anywhere in the article name, set to 0 to search only at the begining
 
 
        global $wgContLang, $wgOut;
        $response = new AjaxResponse();
        $db = wfGetDB( DB_SLAVE );
        $l = new Linker;
 
        $term = str_replace(' ', '_', $term);
 
        if($location == 1){
 
                $res = $db->select( 'page', 'page_title',
                                array(  'page_namespace' => 0,
                                        "UPPER(page_title) LIKE '%" .$db->strencode( strtoupper ($term)). "%'" ),
                                        "wfSajaxSearch",
                                        array( 'LIMIT' => $limit )
                                );
        }else{             
 
                $res = $db->select( 'page', 'page_title',
                        array(  'page_namespace' => 0,
                                "UPPER(page_title) LIKE '". $db->strencode( strtoupper ($term)) ."%'" ),
                                "wfSajaxSearch",
                                array( 'LIMIT' => $limit )
                        );         
        }
 
        $r = "";    
        while ($row = $db->fetchObject( $res ) ){
                $r .= '<li><a href="javascript:Insertlink(\''.addslashes(str_replace('_', ' ', $row->page_title)).'\')">'.str_replace('_', ' ', $row->page_title). "</li>\n";
 
        }
        $html ='<ul>' .$r .'</ul>';
 
        return $html;
}
 
function wfAjaxGoogleTranslateHeaders(){
        global $wgOut;
        wfAjaxSetGoogleTranslateHeaders($wgOut);
        return true;
}
 
 
function wfAjaxSetGoogleTranslateHeaders($outputPage) {
        global $wgJsMimeType, $wgStylePath, $wgScriptPath;
        $outputPage->addLink( 
                array( 
                        'rel' => 'stylesheet', 
                        'type' => 'text/css', 
                        'href' => $wgScriptPath.'/extensions/GoogleTranslate/GoogleTranslate.css' 
                ) 
        );
        $outputPage->addScript( "<script type=\"{$wgJsMimeType}\" src=\"$wgScriptPath/extensions/GoogleTranslate/GoogleTranslate.js\">"."</script>\n");
        $outputPage->addScript( "<script type=\"{$wgJsMimeType}\">hookEvent(\"load\", mwGoogleTranslateButton);</script>\n" );
        $outputPage->addScript( '<script type="text/javascript" src="http://www.google.com/jsapi"></script>' );
      	$outputPage->addScript( '<script type="text/javascript">google.load("language", "1");</script>' ); 
 
}

JavaScript[edit | edit source]

New version, does now work for Firefox - see further here: Google translate problems

/* Hide the translate Extension 
 
*/
 
function trans_hide(obj){ 
        var element = document.getElementById(obj); 
        element.style.display='none'; 
        return true
} 
 
/* Hide the translate Extension 
*/
function translate_text(document){
 
	google.load("language", "1");
 
	var text = wDoc.getElementById("wpTextbox1").value;
	var from_lng = wDoc.getElementById("google_translate_from").value;
	var to_lng = wDoc.getElementById("google_translate_to").value; 
 
	google.language.translate(text, "en", "da", function(result) {  
  	if (!result.error) {    
    	text.value = result.translation;  
    	return true;  
                  }
         });
 
}
 
 
 
function mwGoogleTranslateButton(){   
	/* Load API  
	var script = document.createElement("script");  
  script.src = "http://www.google.com/jsapi";  
  script.type = "text/javascript";  
  document.getElementsByTagName("head")[0].appendChild(script);  */ 
 
 
 
        var toolbar = document.getElementById("toolbar");
        if(!toolbar){
                return false
        }
        var button = document.createElement("a");
        button.href = "#";
 
        button.onclick = function () {
        ls_ajax_onload();
        return false;
        };
 
        var add_image=document.createElement('img');
        add_image.src="skins/common/images/button_translate_da.png";
 
        toolbar.appendChild(button);
        button.appendChild(add_image);
 
        return true
}
 
var ss_memory = null;
 
function GoogleTranslateCall() {
        var newdiv = document.getElementById("GoogleTranslate");
 
        if(!newdiv){
                var newdiv = document.createElement("div");
                newdiv.id = "GoogleTranslate";
                newdiv.style.display='block'
 
                var output = document.getElementById("toolbar");
                output.appendChild(newdiv);
        }
        else{ newdiv.style.display='block'
        } 
        var x = document.getElementById("google_translate_from").value;
 
        if (x == ss_memory) {
        return;
    }
    ss_memory = x;
    if (x.length < 30 && x.length > 2 && x.value != "") {
        sajax_do_call("wfAjaxGoogleTranslate", [x], newdiv);
        }
}
// -----------------------------------------------------------------------
// Next two functions try is used to split text in sentences and linebreaks
// Can be extended to deal with parser things like <code ...> and others! 
 
 
// function returns the next full stopposition  in a string 
function nextStop(text) { 
	 var pos = text.length;
	 var pos2 = text.indexOf(".");
	 if (pos2 > 0 && pos >pos2) { pos = pos2 + 1};                                       // lastPos is the next Sentence stats 
	 var pos2 = text.indexOf("!");
	 if (pos2 > 0 && pos >pos2) { pos = pos2 + 1}; 
	 var pos2 = text.indexOf("?");
	 if (pos2 > 0 && pos >pos2) { pos = pos2 + 1};
 
	 var patt1 = /\x10/; 
	 var pos2 = text.search(patt1);                         
	 if (pos2 > 0 && pos >pos2) { pos = pos2}; 
 
	 var patt1 = /\x13/; 
	 var pos2 = text.search(patt1);                         
	 if (pos2 > 0 && pos >pos2) { pos = pos2}; 
 
	 var patt1 = /\n/; 
	 var pos2 = text.search(patt1);                         
	 if (pos2 > 0 && pos >pos2) { pos = pos2}; 
 
	 if (pos == 0) { pos = text.length };
 
   return pos; 
 
 
}
// If there are more than one . ! ? or "\n" we need to move a bit forward to the next actual string 
// Figure out the next start position, eg after things like .!? and \n 
function nextStart(text) { 
	 var newStart = 1; 
	 var retStart = 0;
	 var pos = -1; // Previous char 
	 var posX = 0; 
	 var aText = text; // work your way through this 
	 while (pos < newStart) {
	 	 pos = newStart; // exit condition 
	 	 posX = aText.indexOf(".");
	 	 if (newStart == posX) {
	 	 	newStart++; };
	 	 posX = aText.indexOf("!");
	 	 if (newStart == posX) {
	 	 	newStart++; };
	 	 posX = aText.indexOf("?");
	 	 if (newStart == posX) {
	 	 	newStart++; };
 
	 	 var patt1 = /\x13/; // are you sure you are not looking for "\r" (#13 decimal, not hex)?
	 	 posX = aText.search(patt1) + 1;
	 	 if (newStart == posX) {
	 	 	newStart++; };
 
	 	 var patt1 = /\x10/; // are you sure you are not looking for "\n" (#10 decimal, not hex)?
	 	 posX = aText.search(patt1) + 1;
	 	 if (newStart == posX) {
	 	 	newStart++; };
 
 
	 	 var patt1 = /\n/;
	 	 // var patt1 = new RegExp("\n");
	 	 posX = aText.search(patt1) + 1;
// document.write("********** funde ved : " + posX);
	 	 // posX = aText.indexOf("\n") + 1;
	 	 if (newStart == posX) {
	 	 	newStart++; };
 
	 	  if (pos < newStart) {
	 	  	retStart += newStart; 
	 	  	pos = newStart - 1;  
	 	  	aText = aText.substring(pos);  // One more round!! 
	      }
	    } 
	   //  retStart--;
	  	return retStart
	}
 
 
 
/* 
    This function builds the translation bar eg. the text 'Translate from/to' etc. 
     - it also attempts to load the API, what a mess
 
    */  
function ls_ajax_onload() {
        // Change to your language specific texts 
        var from_to_text = "Oversæt fra/til: ";                // " Translate from/to: "
        var translate_text = " klik her for at oversætte nu ";   // " click here to translate "       
       var close_text = " ( luk oversætter værktøjet. ) ";     // " ( close translate tool ) "       
 
        var newdiv = document.getElementById("googlelanguage");
        if (!newdiv) {
 
                var newdiv = document.createElement("div");
                newdiv.id = "googlelanguage";
 
                var output = document.getElementById("toolbar");
                output.appendChild(newdiv);
 
                var search = document.createTextNode(from_to_text);
                newdiv.appendChild(search);
 
                var html = document.createElement("input");
                html.id = "google_translate_from";
 
                newdiv.appendChild(html);
 
                var x = document.getElementById( 'google_translate_from' );
                x.value = 'en';
 
                var lng_slash = document.createTextNode(" / ");
                newdiv.appendChild(lng_slash);
 
                var html = document.createElement("input");
                html.id = "google_translate_to";
 
                newdiv.appendChild(html);
 
                var y = document.getElementById( 'google_translate_to' );
                y.value = 'da';
 
 
                var transl = document.createElement("transl");
                transl.href = "#";
 
                transl.onclick = function () {
                  	google.load("language", "1");
                    var myTranslate=function(el,str,startPos, endPos) {
                          return function(result){
                            if(!result.error) { 
                            	 var strX = "Visit W3Schools.\n Learn JavaScript."; 
                               var patt1 = /\n/;
                               var resultX = strX.search(patt1);
 
                              var x=el.innerHTML;
                              // + "/" +  startPos + "/" + endPos
                              // var myX = x.replace(str,result.translation + "/" +  startPos + "/" + endPos + " (" + resultX + ")\n");
                              var myX = x.replace(str,result.translation);
                              el.innerHTML=myX; 
									                }
										      else {
												var xx = result;    // Just to stop and see 
											  return result; } // or other error processing 
 
											}
  									}; 
             /*     	translate_text(document); */
 
	                  var from_lng = document.getElementById("google_translate_from").value;
	                  var to_lng = document.getElementById("google_translate_to").value; 
 
                    var el = document.getElementById("wpTextbox1");    
	                  var text = document.getElementById("wpTextbox1").innerHTML;
                    // var text = text.replace(/\x10/,/\n/);
	                  // var text = text.replace(/\x13/,/\r/);
	                  // text = textConv(text);
 
                    var mLen = text.length;
                    var tStart = nextStart(text); // In case there are '\n' to start?
                    var tNext = nextStop(text,tStart);
                    var xNext = 0; 
 
                   // The real translation takes off here!	         
	                 while (tNext < text.length) { 
	                    var wText = text.substring(tStart, tNext); 
 
                      google.language.translate(wText, from_lng , to_lng , myTranslate(el,wText,tStart,tNext) );
 
                      tNext = tNext + 1;
                      tStart = tNext; 
                      var tStart = nextStart(text.substring(tNext)) + tStart; 
                      tNext = nextStop(text.substring(tStart)) + tStart;
 
                      if (tNext == -1) { tNext =text.length; } 
 
	                  }; 
	                  return;
                };
 
                newdiv.appendChild(transl);    
 
                var transl_text = document.createTextNode(translate_text);
                transl.appendChild(transl_text);
 
 
                var hide = document.createElement("a");
                hide.href = "#";
 
                hide.onclick = function () {
                        trans_hide('googlelanguage');
                        return false;
                };
 
                newdiv.appendChild(hide);    
 
                var hide_text = document.createTextNode(close_text);
                hide.appendChild(hide_text);
 
 
        }else{
                var x = document.getElementById( 'google_translate_from' );
                var element = document.getElementById('googlelanguage'); 
                element.style.display='';
        } 
 
        x.onkeyup = function(){
                GoogleTranslateCall();
    }
}
 
 
function Insertlink(name) {
        var input = document.getElementById("google_translate_from");
        input.value = '';
 
        trans_hide('googletranslate');
        insertTags('[['+name+']]', '', '');              
} 
 
 
document.onclick=check; 
 
function check(e){ 
        var target = (e && e.target) || (event && event.srcElement); 
        var obj = document.getElementById('googletranslate'); 
        if (obj) {
                var parent = checkParent(target); 
                if(parent){
                        obj.style.display='none';
                } 
        } 
} 
 
function checkParent(t){ 
        while(t.parentNode){ 
                if(t==document.getElementById('googletranslate')){ 
                        return false 
                } 
                t=t.parentNode 
        } 
        return true 
}

CSS[edit | edit source]

#googletranslate {
        float: left;
        position: absolute;
        z-index: 3;
        text-align: left;
        border: 1px solid #737373;
        font-size: 11px;
        width: 300px;
        border-top-style: none;
        background-color: white;
        padding-top: .5em;
        padding-bottom: 1em;
        margin-left: .5em;
}
 
#google_translate_input{
        border: 1px solid #333;
}
 
#google_translate_from{
        border: 1px solid #333;
}
#google_translate_to{
        border: 1px solid #333;
}
 
 
 
#googletranslate a {
        color: black;
        background: #7cff00;
        padding-left: .5em;
        display: block;
        font-weight: bold;
        font-style: normal;
}
 
#googletranslate ul{
        list-style: none;
        margin: 0;
 
}
 
#googletranslate li{
        padding:1px 5px;
        white-space: nowrap;
        text-align:left;
        margin: 0;
 
}
 
#googletranslate a:hover{
        font-weight: bold;
        text-decoration: underline;
        background: white;
        color: #4a1500;
 
}
 
#googlelanguage {
        text-align: left;
        border: 1px solid #737373;
        padding: .5em;
}

Ideas[edit | edit source]

Please add ideas here:

  • May integrate into this: FCKEditor
  • Needs a preview function
  • Needs a 'translate and create new article' function

Tools to use[edit | edit source]

Code in progress[edit | edit source]

Please observe: This code does not work right not, it is a prototype! You will need to install Extension Link suggest, to get the button! (will be added as soon as I get a PNG editor :-)

The following is to-do before this will work:

  • Load and link to GoogleTranslate
  • Dropdownlists for the languages
See code to build dropdown box contents here - view the source: Googles dynamic translate sample
  • Default languages to be setup in localsettings.php
How do I get params like $wgContLang passed to the .js code?????
  • Fetch and replace the edit text (have to figure out how to)

Google AJAX API - dynamic load[edit | edit source]

See more here: Google API examples

function initLoader() {
  var script = document.createElement("script");  
  script.src = "http://www.google.com/jsapi?key=ABCDEFG&callback=loadMaps";  
  script.type = "text/javascript";  
  document.getElementsByTagName("head")[0].appendChild(script);
 
  google.load("language", "1");
}

Google translate codesnip[edit | edit source]

Sample of how to edit directly is found here: [[[Extension:TEX Editor/Code|TEX Editor]]]

var text = document.getElementById("wpTextbox1").value;
var from_lng = document.getElementById("google_translate_from").value;
var to_lng = document.getElementById("google_translate_to").value;
 
google.language.translate(text, from_lng, to_lng, function(result) {  
  if (!result.error) {    
    document.getElementById("wpTextbox1").value = result.translation;  
}
});