diff --git a/classes/pluginhost.php b/classes/pluginhost.php
index 96b1ce499bb4ef48b4c5e39f80d9e677607f47b9..2ad9ae11d419f12be9311e204de038c035a47fc2 100755
--- a/classes/pluginhost.php
+++ b/classes/pluginhost.php
@@ -1,4 +1,18 @@
 <?php
+/* gettext helpers for plugins */
+
+function P__($plugin, $msgid) {
+	return P_gettext($plugin, $msgid);
+}
+
+function P_gettext($plugin, $msgid) {
+	return _dgettext(PLuginHost::object_to_domain($plugin), $msgid);
+}
+
+function P_ngettext($plugin, $singular, $plural, $number) {
+	return _dngettext(PLuginHost::object_to_domain($plugin), $singular, $plural, $number);
+}
+
 class PluginHost {
 	private $pdo;
 	private $hooks = array();
@@ -63,6 +77,10 @@ class PluginHost {
 	const KIND_SYSTEM = 2;
 	const KIND_USER = 3;
 
+	static function object_to_domain($plugin) {
+		return strtolower(get_class($plugin));
+	}
+
 	function __construct() {
 		$this->pdo = Db::pdo();
 
@@ -211,6 +229,11 @@ class PluginHost {
 						continue;
 					}
 
+					if (file_exists(dirname($file) . "/locale")) {
+						_bindtextdomain($class, dirname($file) . "/locale");
+						_bind_textdomain_codeset($class, "UTF-8");
+					}
+
 					$this->last_registered = $class;
 
 					switch ($kind) {
diff --git a/include/functions.php b/include/functions.php
index 6a612115e7a1a9545fe4232e0545c255418b01a6..8c0654f3c64b3fde55c52f238fc2cd659bda5bfc 100755
--- a/include/functions.php
+++ b/include/functions.php
@@ -141,7 +141,6 @@
 			}
 
 			_bindtextdomain("messages", "locale");
-
 			_textdomain("messages");
 			_bind_textdomain_codeset("messages", "UTF-8");
 		}
@@ -2403,18 +2402,23 @@
 				return __((parseInt(n) > 1) ? msg2 : msg1);
 			}';
 
-		$l10n = _get_reader();
+		global $text_domains;
 
-		for ($i = 0; $i < $l10n->total; $i++) {
-			$orig = $l10n->get_original_string($i);
-			if(strpos($orig, "\000") !== FALSE) { // Plural forms
-				$key = explode(chr(0), $orig);
-				print T_js_decl($key[0], _ngettext($key[0], $key[1], 1)); // Singular
-				print T_js_decl($key[1], _ngettext($key[0], $key[1], 2)); // Plural
-			} else {
-				$translation = __($orig);
-				print T_js_decl($orig, $translation);
+		foreach (array_keys($text_domains) as $domain) {
+			$l10n = _get_reader($domain);
+
+			for ($i = 0; $i < $l10n->total; $i++) {
+				$orig = $l10n->get_original_string($i);
+				if(strpos($orig, "\000") !== FALSE) { // Plural forms
+					$key = explode(chr(0), $orig);
+					print T_js_decl($key[0], _ngettext($key[0], $key[1], 1)); // Singular
+					print T_js_decl($key[1], _ngettext($key[0], $key[1], 2)); // Plural
+				} else {
+					$translation = _dgettext($domain,$orig);
+					print T_js_decl($orig, $translation);
+				}
 			}
+
 		}
 	}