From 151eebcc289884259e18e95b2d707a2fc1c72b0e Mon Sep 17 00:00:00 2001 From: Brion Vibber Date: Tue, 2 Nov 2010 11:39:38 -0700 Subject: [PATCH 1/7] Starting on making Realtime plugin's UI messages localizable: pause/play, popup button text and tooltip text are now loaded from PHP code where we can get at gettext. --- plugins/Realtime/RealtimePlugin.php | 24 ++++++++++++++++++++++++ plugins/Realtime/realtimeupdate.js | 24 ++++++++++++++---------- 2 files changed, 38 insertions(+), 10 deletions(-) diff --git a/plugins/Realtime/RealtimePlugin.php b/plugins/Realtime/RealtimePlugin.php index 352afcf785..7a40cdca31 100644 --- a/plugins/Realtime/RealtimePlugin.php +++ b/plugins/Realtime/RealtimePlugin.php @@ -106,7 +106,9 @@ class RealtimePlugin extends Plugin $realtimeUI = ' RealtimeUpdate.initActions("'.$url.'", "'.$timeline.'", "'. $pluginPath .'");'; } + $i18n = $this->_getMessages(); $script = ' $(document).ready(function() { '. + 'RealtimeUpdate._messages=' . json_encode($i18n) . ';' . $realtimeUI. $this->_updateInitialize($timeline, $user_id). '}); '; @@ -326,6 +328,28 @@ class RealtimePlugin extends Plugin return array('plugins/Realtime/realtimeupdate.js'); } + /** + * Any i18n messages that need to be loaded at runtime. + * @return array of string key to output text string pairs + */ + function _getMessages() + { + return array( + // TRANS: Text label for realtime view "play" button, usually replaced by an icon. + 'play' => _m('BUTTON', 'Play'), + // TRANS: Tooltip for realtime view "play" button. + 'play_tooltip' => _m('TOOLTIP', 'Play'), + // TRANS: Text label for realtime view "pause" button + 'pause' => _m('BUTTON', 'Pause'), + // TRANS: Tooltip for realtime view "pause" button + 'pause_tooltip' => _m('TOOLTIP', 'Pause'), + // TRANS: Text label for realtime view "popup" button, usually replaced by an icon. + 'popup' => _m('BUTTON', 'Pop up'), + // TRANS: Tooltip for realtime view "popup" button. + 'popup_tooltip' => _m('TOOLTIP', 'Pop up in a window'), + ); + } + function _updateInitialize($timeline, $user_id) { return "RealtimeUpdate.init($user_id, \"$this->replyurl\", \"$this->favorurl\", \"$this->repeaturl\", \"$this->deleteurl\"); "; diff --git a/plugins/Realtime/realtimeupdate.js b/plugins/Realtime/realtimeupdate.js index 25dc12d584..f764ca738d 100644 --- a/plugins/Realtime/realtimeupdate.js +++ b/plugins/Realtime/realtimeupdate.js @@ -40,6 +40,7 @@ RealtimeUpdate = { _documenttitle: '', _paused:false, _queuedNotices:[], + _messages:{}, init: function(userid, replyurl, favorurl, repeaturl, deleteurl) { @@ -261,9 +262,10 @@ RealtimeUpdate = { RealtimeUpdate.addNoticesHover(); $('#realtime_playpause').remove(); - $('#realtime_actions').prepend('
  • '); - - $('#realtime_pause').bind('click', function() { + $('#realtime_actions').prepend('
  • '); + $('#realtime_pause').text(RealtimeUpdate._messages['pause']) + .attr('title', RealtimeUpdate._messages['pause_tooltip']) + .bind('click', function() { RealtimeUpdate.removeNoticesHover(); RealtimeUpdate.showPlay(); return false; @@ -274,9 +276,10 @@ RealtimeUpdate = { { RealtimeUpdate.setPause(true); $('#realtime_playpause').remove(); - $('#realtime_actions').prepend('
  • '); - - $('#realtime_play').bind('click', function() { + $('#realtime_actions').prepend('
  • '); + $('#realtime_play').text(RealtimeUpdate._messages['play']) + .attr('title', RealtimeUpdate._messages['play_tooltip']) + .bind('click', function() { RealtimeUpdate.showPause(); return false; }); @@ -334,10 +337,11 @@ RealtimeUpdate = { initAddPopup: function(url, timeline, path) { - $('#realtime_timeline').append(''); - - $('#realtime_popup').bind('click', function() { - window.open(url, + $('#realtime_timeline').append(''); + $('#realtime_popup').text(RealtimeUpdate._messages['popup']) + .attr('title', RealtimeUpdate._messages['popup_tooltip']) + .bind('click', function() { + window.open(url, '', 'toolbar=no,resizable=yes,scrollbars=yes,status=no,menubar=no,personalbar=no,location=no,width=500,height=550'); From 194bb022526d2f2fcc447a0e4835a4e5bb12baa2 Mon Sep 17 00:00:00 2001 From: Siebrand Mazeland Date: Tue, 2 Nov 2010 20:49:34 +0100 Subject: [PATCH 2/7] * add POT file * remove superfluous whitespace * break lines at 80 or before in README --- plugins/Realtime/README | 4 +-- plugins/Realtime/RealtimePlugin.php | 1 - plugins/Realtime/locale/Realtime.pot | 53 ++++++++++++++++++++++++++++ plugins/Realtime/realtimeupdate.css | 2 -- 4 files changed, 55 insertions(+), 5 deletions(-) create mode 100644 plugins/Realtime/locale/Realtime.pot diff --git a/plugins/Realtime/README b/plugins/Realtime/README index 99c79cfab5..9b36d87f37 100644 --- a/plugins/Realtime/README +++ b/plugins/Realtime/README @@ -5,6 +5,6 @@ * Pause ~ retain up to 50-100 most recent notices * Add geo data * Make it work for Conversation page (perhaps a little tricky) -* IE is updating the counter in document title all the time (Not sure if this is still an issue) +* IE is updating the counter in document title all the time (Not sure if this + is still an issue) * Reconsider the timestamp approach - diff --git a/plugins/Realtime/RealtimePlugin.php b/plugins/Realtime/RealtimePlugin.php index 7a40cdca31..23e8fb4d9e 100644 --- a/plugins/Realtime/RealtimePlugin.php +++ b/plugins/Realtime/RealtimePlugin.php @@ -43,7 +43,6 @@ if (!defined('STATUSNET') && !defined('LACONICA')) { * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0 * @link http://status.net/ */ - class RealtimePlugin extends Plugin { protected $replyurl = null; diff --git a/plugins/Realtime/locale/Realtime.pot b/plugins/Realtime/locale/Realtime.pot new file mode 100644 index 0000000000..e491ce0c75 --- /dev/null +++ b/plugins/Realtime/locale/Realtime.pot @@ -0,0 +1,53 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2010-11-02 19:46+0000\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=CHARSET\n" +"Content-Transfer-Encoding: 8bit\n" + +#. TRANS: Text label for realtime view "play" button, usually replaced by an icon. +#: RealtimePlugin.php:339 +msgctxt "BUTTON" +msgid "Play" +msgstr "" + +#. TRANS: Tooltip for realtime view "play" button. +#: RealtimePlugin.php:341 +msgctxt "TOOLTIP" +msgid "Play" +msgstr "" + +#. TRANS: Text label for realtime view "pause" button +#: RealtimePlugin.php:343 +msgctxt "BUTTON" +msgid "Pause" +msgstr "" + +#. TRANS: Tooltip for realtime view "pause" button +#: RealtimePlugin.php:345 +msgctxt "TOOLTIP" +msgid "Pause" +msgstr "" + +#. TRANS: Text label for realtime view "popup" button, usually replaced by an icon. +#: RealtimePlugin.php:347 +msgctxt "BUTTON" +msgid "Pop up" +msgstr "" + +#. TRANS: Tooltip for realtime view "popup" button. +#: RealtimePlugin.php:349 +msgctxt "TOOLTIP" +msgid "Pop up in a window" +msgstr "" diff --git a/plugins/Realtime/realtimeupdate.css b/plugins/Realtime/realtimeupdate.css index f43c97de52..b277b30a14 100644 --- a/plugins/Realtime/realtimeupdate.css +++ b/plugins/Realtime/realtimeupdate.css @@ -35,7 +35,6 @@ width:70%; margin-left:1%; } - #notices_primary { position:relative; } @@ -75,4 +74,3 @@ line-height:1.2; #showstream #notices_primary { margin-top: 18px; } - From 5a9bb0adc4555bf67bb668edb587d4440cca61e5 Mon Sep 17 00:00:00 2001 From: Brion Vibber Date: Tue, 2 Nov 2010 13:05:16 -0700 Subject: [PATCH 3/7] Tossing in a basic i18n message export to script code. Plugins can hook StartScriptMessage/EndScriptMessage, or directly add needed mappings in Action::getScriptMessages(). Exported entries are accessible as SN.msg(key) at runtime. StatusNet core code now sets the tooltip text on .attachment.more links when they receive their attachment-expansion magic; this will override the hardcoded tooltip text saved from OStatus plugin when displaying timelines in the web UI. --- js/util.js | 11 ++++- lib/action.php | 49 +++++++++++++++++++++ plugins/OStatus/classes/Ostatus_profile.php | 3 +- 3 files changed, 61 insertions(+), 2 deletions(-) diff --git a/js/util.js b/js/util.js index 1989e92c09..1be3f30535 100644 --- a/js/util.js +++ b/js/util.js @@ -56,6 +56,15 @@ var SN = { // StatusNet NoticeDataGeoCookie: 'NoticeDataGeo', NoticeDataGeoSelected: 'notice_data-geo_selected', StatusNetInstance:'StatusNetInstance' + }, + }, + + messages: {}, + msg: function(key) { + if (typeof SN.messages[key] == "undefined") { + return '[' + key + ']'; + } else { + return SN.messages[key]; } }, @@ -416,7 +425,7 @@ var SN = { // StatusNet }); return false; - }); + }).attr('title', SN.msg('showmore_tooltip')); } else { $.fn.jOverlay.options = { diff --git a/lib/action.php b/lib/action.php index 01bb0f7e92..becd734b10 100644 --- a/lib/action.php +++ b/lib/action.php @@ -283,6 +283,7 @@ class Action extends HTMLOutputter // lawsuit if (Event::handle('StartShowStatusNetScripts', array($this)) && Event::handle('StartShowLaconicaScripts', array($this))) { $this->script('util.js'); + $this->showScriptMessages(); // Frame-busting code to avoid clickjacking attacks. $this->inlineScript('if (window.top !== window.self) { window.top.location.href = window.self.location.href; }'); Event::handle('EndShowStatusNetScripts', array($this)); @@ -292,6 +293,54 @@ class Action extends HTMLOutputter // lawsuit } } + /** + * Exports a map of localized text strings to JavaScript code. + * + * Plugins can add to what's exported by hooking the StartScriptMessages or EndScriptMessages + * events and appending to the array. Try to avoid adding strings that won't be used, as + * they'll be added to HTML output. + */ + function showScriptMessages() + { + $messages = array(); + if (Event::handle('StartScriptMessages', array($this, &$messages))) { + // Common messages needed for timeline views etc... + + // TRANS: Localized tooltip for '...' expansion button on overlong remote messages. + $messages['showmore_tooltip'] = _m('TOOLTIP', 'Show more'); + + $messages = array_merge($messages, $this->getScriptMessages()); + } + if ($messages) { + $this->inlineScript('SN.messages=' . json_encode($messages)); + } + Event::handle('EndScriptMessages', array($this, &$messages)); + return $messages; + } + + /** + * If the action will need localizable text strings, export them here like so: + * + * return array('pool_deepend' => _('Deep end'), + * 'pool_shallow' => _('Shallow end')); + * + * The exported map will be available via SN.msg() to JS code: + * + * $('#pool').html('
    '); + * $('#pool .deepend').text(SN.msg('pool_deepend')); + * $('#pool .shallow').text(SN.msg('pool_shallow')); + * + * Exports a map of localized text strings to JavaScript code. + * + * Plugins can add to what's exported on any action by hooking the StartScriptMessages or + * EndScriptMessages events and appending to the array. Try to avoid adding strings that won't + * be used, as they'll be added to HTML output. + */ + function getScriptMessages() + { + return array(); + } + /** * Show OpenSearch headers * diff --git a/plugins/OStatus/classes/Ostatus_profile.php b/plugins/OStatus/classes/Ostatus_profile.php index 03fcb71df0..90bf671eb1 100644 --- a/plugins/OStatus/classes/Ostatus_profile.php +++ b/plugins/OStatus/classes/Ostatus_profile.php @@ -588,7 +588,8 @@ class Ostatus_profile extends Memcached_DataObject // We mark up the attachment link specially for the HTML output // so we can fold-out the full version inline. - // TRANS: Shown when a notice is longer than supported and/or when attachments are present. + // @fixme I18N this tooltip will be saved with the site's default language + // TRANS: Shown when a notice is longer than supported and/or when attachments are present. At runtime this will usually be replaced with localized text from StatusNet core messages. $showMoreText = _m('Show more'); $attachUrl = common_local_url('attachment', array('attachment' => $attachment->id)); From 86201761eadef3b124ee13e6ba2f9e661e697a5a Mon Sep 17 00:00:00 2001 From: Brion Vibber Date: Tue, 2 Nov 2010 13:12:58 -0700 Subject: [PATCH 4/7] Use SN.msg() and onEndScriptMessages() to export localized UI messages from Realtime plugin and its descendents. --- lib/action.php | 2 +- plugins/Realtime/RealtimePlugin.php | 40 +++++++++++++++-------------- plugins/Realtime/realtimeupdate.js | 13 +++++----- 3 files changed, 28 insertions(+), 27 deletions(-) diff --git a/lib/action.php b/lib/action.php index becd734b10..766cfca269 100644 --- a/lib/action.php +++ b/lib/action.php @@ -311,10 +311,10 @@ class Action extends HTMLOutputter // lawsuit $messages = array_merge($messages, $this->getScriptMessages()); } + Event::handle('EndScriptMessages', array($this, &$messages)); if ($messages) { $this->inlineScript('SN.messages=' . json_encode($messages)); } - Event::handle('EndScriptMessages', array($this, &$messages)); return $messages; } diff --git a/plugins/Realtime/RealtimePlugin.php b/plugins/Realtime/RealtimePlugin.php index 7a40cdca31..479e8cef2f 100644 --- a/plugins/Realtime/RealtimePlugin.php +++ b/plugins/Realtime/RealtimePlugin.php @@ -106,9 +106,7 @@ class RealtimePlugin extends Plugin $realtimeUI = ' RealtimeUpdate.initActions("'.$url.'", "'.$timeline.'", "'. $pluginPath .'");'; } - $i18n = $this->_getMessages(); $script = ' $(document).ready(function() { '. - 'RealtimeUpdate._messages=' . json_encode($i18n) . ';' . $realtimeUI. $this->_updateInitialize($timeline, $user_id). '}); '; @@ -329,25 +327,29 @@ class RealtimePlugin extends Plugin } /** - * Any i18n messages that need to be loaded at runtime. - * @return array of string key to output text string pairs + * Export any i18n messages that need to be loaded at runtime... + * + * @param Action $action + * @param array $messages + * + * @return boolean hook return value */ - function _getMessages() + function onEndScriptMessages($action, &$messages) { - return array( - // TRANS: Text label for realtime view "play" button, usually replaced by an icon. - 'play' => _m('BUTTON', 'Play'), - // TRANS: Tooltip for realtime view "play" button. - 'play_tooltip' => _m('TOOLTIP', 'Play'), - // TRANS: Text label for realtime view "pause" button - 'pause' => _m('BUTTON', 'Pause'), - // TRANS: Tooltip for realtime view "pause" button - 'pause_tooltip' => _m('TOOLTIP', 'Pause'), - // TRANS: Text label for realtime view "popup" button, usually replaced by an icon. - 'popup' => _m('BUTTON', 'Pop up'), - // TRANS: Tooltip for realtime view "popup" button. - 'popup_tooltip' => _m('TOOLTIP', 'Pop up in a window'), - ); + // TRANS: Text label for realtime view "play" button, usually replaced by an icon. + $messages['realtime_play'] = _m('BUTTON', 'Play'); + // TRANS: Tooltip for realtime view "play" button. + $messages['realtime_play_tooltip'] = _m('TOOLTIP', 'Play'); + // TRANS: Text label for realtime view "pause" button + $messages['realtime_pause'] = _m('BUTTON', 'Pause'); + // TRANS: Tooltip for realtime view "pause" button + $messages['realtime_pause_tooltip'] = _m('TOOLTIP', 'Pause'); + // TRANS: Text label for realtime view "popup" button, usually replaced by an icon. + $messages['realtime_popup'] = _m('BUTTON', 'Pop up'); + // TRANS: Tooltip for realtime view "popup" button. + $messages['realtime_popup_tooltip'] = _m('TOOLTIP', 'Pop up in a window'); + + return true; } function _updateInitialize($timeline, $user_id) diff --git a/plugins/Realtime/realtimeupdate.js b/plugins/Realtime/realtimeupdate.js index f764ca738d..f49cef95e6 100644 --- a/plugins/Realtime/realtimeupdate.js +++ b/plugins/Realtime/realtimeupdate.js @@ -40,7 +40,6 @@ RealtimeUpdate = { _documenttitle: '', _paused:false, _queuedNotices:[], - _messages:{}, init: function(userid, replyurl, favorurl, repeaturl, deleteurl) { @@ -263,8 +262,8 @@ RealtimeUpdate = { $('#realtime_playpause').remove(); $('#realtime_actions').prepend('
  • '); - $('#realtime_pause').text(RealtimeUpdate._messages['pause']) - .attr('title', RealtimeUpdate._messages['pause_tooltip']) + $('#realtime_pause').text(SN.msg('realtime_pause')) + .attr('title', SN.msg('realtime_pause_tooltip')) .bind('click', function() { RealtimeUpdate.removeNoticesHover(); RealtimeUpdate.showPlay(); @@ -277,8 +276,8 @@ RealtimeUpdate = { RealtimeUpdate.setPause(true); $('#realtime_playpause').remove(); $('#realtime_actions').prepend('
  • '); - $('#realtime_play').text(RealtimeUpdate._messages['play']) - .attr('title', RealtimeUpdate._messages['play_tooltip']) + $('#realtime_play').text(SN.msg('realtime_play')) + .attr('title', SN.msg('realtime_play_tooltip')) .bind('click', function() { RealtimeUpdate.showPause(); return false; @@ -338,8 +337,8 @@ RealtimeUpdate = { initAddPopup: function(url, timeline, path) { $('#realtime_timeline').append(''); - $('#realtime_popup').text(RealtimeUpdate._messages['popup']) - .attr('title', RealtimeUpdate._messages['popup_tooltip']) + $('#realtime_popup').text(SN.msg('realtime_popup')) + .attr('title', SN.msg('realtime_popup_tooltip')) .bind('click', function() { window.open(url, '', From 426cda5e1ffd365b6b8915e8d504c0a6672339d3 Mon Sep 17 00:00:00 2001 From: Brion Vibber Date: Tue, 2 Nov 2010 13:42:33 -0700 Subject: [PATCH 5/7] Alternate pretty-title tweaks for #2668 --- actions/showstream.php | 10 ++++------ classes/Profile.php | 21 +++++++++++++++++++++ 2 files changed, 25 insertions(+), 6 deletions(-) diff --git a/actions/showstream.php b/actions/showstream.php index fb5b061fbe..de66bc415a 100644 --- a/actions/showstream.php +++ b/actions/showstream.php @@ -63,18 +63,16 @@ class ShowstreamAction extends ProfileAction function title() { - if (!empty($this->profile->fullname)) { - $base = $this->profile->fullname . ' (' . $this->user->nickname . ') '; - } else { - $base = $this->user->nickname; - } + $base = $this->profile->getFancyName(); if (!empty($this->tag)) { - $base .= sprintf(_(' tagged %s'), $this->tag); + // TRANS: Page title showing tagged notices in one user's stream. Param 1 is the username, 2 is the hash tag. + $base = sprintf(_('%1$s tagged %2$s'), $base, $this->tag); } if ($this->page == 1) { return $base; } else { + // TRANS: Extended page title showing tagged notices in one user's stream. Param 1 is the main title clause; 2 is the page number. return sprintf(_('%1$s, page %2$d'), $base, $this->page); diff --git a/classes/Profile.php b/classes/Profile.php index 37d2c571f9..064ba551c4 100644 --- a/classes/Profile.php +++ b/classes/Profile.php @@ -141,11 +141,32 @@ class Profile extends Memcached_DataObject return true; } + /** + * Gets either the full name (if filled) or the nickname. + * + * @return string + */ function getBestName() { return ($this->fullname) ? $this->fullname : $this->nickname; } + /** + * Gets the full name (if filled) with nickname as a parenthetical, or the nickname alone + * if no fullname is provided. + * + * @return string + */ + function getFancyName() + { + if ($this->fullname) { + // TRANS: Full name of a profile or group followed by nickname in parens + return sprintf(_('%1$s (%2$s)'), $this->fullname, $this->nickname); + } else { + return $this->nickname; + } + } + /** * Get the most recent notice posted by this user, if any. * From bc85f6914be97e1b44891153dc96045dfcefcaf6 Mon Sep 17 00:00:00 2001 From: Brion Vibber Date: Tue, 2 Nov 2010 14:03:50 -0700 Subject: [PATCH 6/7] fix syntax error introduced in i18n tweaks: newgroup action --- actions/newgroup.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/actions/newgroup.php b/actions/newgroup.php index 9c1870b1c6..e0e7978c32 100644 --- a/actions/newgroup.php +++ b/actions/newgroup.php @@ -151,7 +151,7 @@ class NewgroupAction extends Action // TRANS: %d is the maximum number of allowed characters. $this->showForm(sprintf(_m('Description is too long (maximum %d character).', 'Description is too long (maximum %d characters).', - User_group::maxDescription(), + User_group::maxDescription()), User_group::maxDescription())); return; } else if (!is_null($location) && mb_strlen($location) > 255) { From 6a181bb12837f477dcaa13619024de2f984b7f20 Mon Sep 17 00:00:00 2001 From: Brion Vibber Date: Tue, 2 Nov 2010 14:20:06 -0700 Subject: [PATCH 7/7] Unrolled tagged vs untagged, page 1 vs page N message variants for showstream title. #2668 --- actions/showstream.php | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/actions/showstream.php b/actions/showstream.php index de66bc415a..dd6c91b004 100644 --- a/actions/showstream.php +++ b/actions/showstream.php @@ -65,17 +65,22 @@ class ShowstreamAction extends ProfileAction { $base = $this->profile->getFancyName(); if (!empty($this->tag)) { - // TRANS: Page title showing tagged notices in one user's stream. Param 1 is the username, 2 is the hash tag. - $base = sprintf(_('%1$s tagged %2$s'), $base, $this->tag); - } - - if ($this->page == 1) { - return $base; + if ($this->page == 1) { + // TRANS: Page title showing tagged notices in one user's stream. Param 1 is the username, 2 is the hash tag. + return sprintf(_('%1$s tagged %2$s'), $base, $this->tag); + } else { + // TRANS: Page title showing tagged notices in one user's stream. Param 1 is the username, 2 is the hash tag, 3 is the page number. + return sprintf(_('%1$s tagged %2$s, page %3$d'), $base, $this->tag, $this->page); + } } else { - // TRANS: Extended page title showing tagged notices in one user's stream. Param 1 is the main title clause; 2 is the page number. - return sprintf(_('%1$s, page %2$d'), - $base, - $this->page); + if ($this->page == 1) { + return $base; + } else { + // TRANS: Extended page title showing tagged notices in one user's stream. Param 1 is the username, param 2 is the page number. + return sprintf(_('%1$s, page %2$d'), + $base, + $this->page); + } } }