Author: ncuesta
Date: 2010-05-13 20:08:07 +0200 (Thu, 13 May 2010)
New Revision: 29438
Added:
plugins/ncJavascriptLocalizationPlugin/COPYING.l10n-js.md
plugins/ncJavascriptLocalizationPlugin/LICENSE
plugins/ncJavascriptLocalizationPlugin/README
plugins/ncJavascriptLocalizationPlugin/README.l10n-js.md
plugins/ncJavascriptLocalizationPlugin/config/
plugins/ncJavascriptLocalizationPlugin/config/ncJavascriptLocalizationPluginConfiguration.class.php
plugins/ncJavascriptLocalizationPlugin/lib/
plugins/ncJavascriptLocalizationPlugin/lib/helper/
plugins/ncJavascriptLocalizationPlugin/lib/helper/ncJSL10NHelper.php
plugins/ncJavascriptLocalizationPlugin/lib/l10n/
plugins/ncJavascriptLocalizationPlugin/lib/l10n/ncJSL10N.class.php
plugins/ncJavascriptLocalizationPlugin/lib/routing/
plugins/ncJavascriptLocalizationPlugin/lib/routing/ncJSL10NRouting.class.php
plugins/ncJavascriptLocalizationPlugin/modules/
plugins/ncJavascriptLocalizationPlugin/modules/nc_js_l10n/
plugins/ncJavascriptLocalizationPlugin/modules/nc_js_l10n/actions/
plugins/ncJavascriptLocalizationPlugin/modules/nc_js_l10n/actions/actions.class.php
plugins/ncJavascriptLocalizationPlugin/modules/nc_js_l10n/lib/
plugins/ncJavascriptLocalizationPlugin/modules/nc_js_l10n/lib/BasencJSL10NActions.class.php
plugins/ncJavascriptLocalizationPlugin/web/
plugins/ncJavascriptLocalizationPlugin/web/js/
plugins/ncJavascriptLocalizationPlugin/web/js/global.js
plugins/ncJavascriptLocalizationPlugin/web/js/l10n.js
plugins/ncJavascriptLocalizationPlugin/web/js/l10n.min.js
Log:
Initial commit for ncJavascriptLocalizationPlugin.
Added: plugins/ncJavascriptLocalizationPlugin/COPYING.l10n-js.md
===================================================================
--- plugins/ncJavascriptLocalizationPlugin/COPYING.l10n-js.md
(rev 0)
+++ plugins/ncJavascriptLocalizationPlugin/COPYING.l10n-js.md 2010-05-13
18:08:07 UTC (rev 29438)
@@ -0,0 +1,52 @@
+This program is dual-licensed under the GNU GPL v3 and the
+MIT/X11 license.
+
+
+MIT/X11 license
+---------------
+
+Copyright (c) 2010 [Elijah Grey]
+
+Permission is hereby granted, free of charge, to any person
+obtaining a copy of this software and associated documentation
+files (the "Software"), to deal in the Software without
+restriction, including without limitation the rights to use,
+copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following
+conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+
+GNU GPL v3 license
+------------------
+
+Copyright (c) 2010 [Elijah Grey]
+
+This software is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+
+
+ [Elijah Grey]: http://eligrey.com
Added: plugins/ncJavascriptLocalizationPlugin/LICENSE
===================================================================
--- plugins/ncJavascriptLocalizationPlugin/LICENSE
(rev 0)
+++ plugins/ncJavascriptLocalizationPlugin/LICENSE 2010-05-13 18:08:07 UTC
(rev 29438)
@@ -0,0 +1,7 @@
+Copyright (c) José Nahuel Cuesta Luengo
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
Added: plugins/ncJavascriptLocalizationPlugin/README
===================================================================
--- plugins/ncJavascriptLocalizationPlugin/README
(rev 0)
+++ plugins/ncJavascriptLocalizationPlugin/README 2010-05-13 18:08:07 UTC
(rev 29438)
@@ -0,0 +1,102 @@
+ncJavascriptLocalization plugin
+===============================
+
+The `ncJavascriptLocalizationPlugin` is a symfony plugin that provides
javascript string
+localization based on symfony's built-in i18n and also a glue between
symfony's session
+culture and javascript's `String.locale`.
+
+This plugin uses the great javascript library `l10n.js`
+(see http://eligrey.com/blog/post/localization-in-javascript) written by
Elijah Grey
+(http://eligrey.com/blog/about).
+
+Basically, this plugin allows javascript localization through symfony's i18n
mechanism.
+By using symfony's i18n catalogues, this plugin generates the needed set of
dictionaries
+for the `l10n.js` library, allowing localization without any more hassle than
what
+we are used to ;-)
+
+Installation
+------------
+
+ * Install the plugin
+
+ $ symfony plugin:install ncJavascriptLocalizationPlugin
+
+ * Enable the module in your `settings.yml` (optional): nc_js_l10n
+
+ [yml]
+ all:
+ .settings:
+ enabled_modules: [default, nc_js_l10n]
+
+ * Add the required javascripts to your `view.yml`:
+ [yml]
+ all:
+ # Note that here the minified version of Elijah Grey's l10n.js
is used, but the standard version (l10n.js) is also bundled
+ javascripts:
[/ncJavascriptLocalizationPlugin/js/l10n.min.js,
/ncJavascriptLocalizationPlugin/js/global.js]
+
+ * Add the ncJSL10N helper to your standard helpers in `settings.yml`
(optional, you may manually load it from templates):
+
+ [yml]
+ all:
+ .settings:
+ standard_helpers: [Partial, Cache, I18N, ncJSL10N]
+
+ * Load in your layout's <HEAD> part the links to the JSON-encoded
dictionaries:
+
+ [php]
+ <html>
+ <head>
+ <?php // This way, we only load JSON localization dictionary
for the user's current culture ?>
+ <?php include_js_l10n_json() ?>
+
+ <?php // By passing a specific set of cultures, we load JSON
localization dictionaries for those cultures ?>
+ <?php include_js_l10n_json(array('es_AR', 'pt_BR', 'fr_FR')) ?>
+
+ <?php // There is an optional second parameter that performs
the glue (if set to TRUE)
+ // between symfony's session culture and JS's
String.locale ?>
+ <?php include_js_l10n_json(null, true) // OR could specify
cultures: include_js_l10n_json(array('es_AR', 'pt_BR', 'fr_FR')) ?>
+
+ * Optionally, configure the plugin on your `app.yml`:
+
+ [yml]
+ nc_js_l10n:
+ routes:
+ register: true # default value, you may set
this to false and...
+ custom_route:
+ name: my_custom_route # ...specify your custom route
here
+ param_name: language # default value, name of the
parameter from which target language is obtained
+
+
+ catalogue: nc_js_l10n # default value, you may use any
catalogue
+
+ language:
+ default: en # defaults to user's culture
+ set_sf_culture_for_js: false # default value, specifies
whether the culture from symfony's session is to be
+ # set for javascript
String.locale attribute
+
+ * Clear you cache
+
+ $ symfony cc
+
+Customize nc_js_l10n module actions
+-----------------------------------
+
+By default, `nc_js_l10n` module comes with the following action: `json`. This
actions serves the
+dictionary for the culture specified in the `language` request parameter.
+
+You may extend this default behavior by creating a module in your application
and making its
+actions extend `BasencJSL10NActions`. You will have to include the
`BasencJSL10NActions` as
+symfony won't be autoloaded by symfony:
+
+ [php]
+ <?php
+
+
require_once(sfConfig::get('sf_plugins_dir').'/ncJavascriptLocalizationPlugin/modules/nc_js_l10n/lib/BasencJSL10NActions.class.php');
+
+ class nc_js_l10nActions extends BasencJSL10NActions
+ {
+ public function executeMyAction()
+ {
+ // Do your trick!
+ }
+ }
Added: plugins/ncJavascriptLocalizationPlugin/README.l10n-js.md
===================================================================
--- plugins/ncJavascriptLocalizationPlugin/README.l10n-js.md
(rev 0)
+++ plugins/ncJavascriptLocalizationPlugin/README.l10n-js.md 2010-05-13
18:08:07 UTC (rev 29438)
@@ -0,0 +1,242 @@
+l10n.js
+=======
+
+l10n.js is a JavaScript library that enables localization through the native
JavaScript
+method intended for it, gracefully degrading if the library is not present. As
it
+gracefully degrades, you can make Ajax applications, JavaScript libraries,
etc. that can
+be localized but not require l10n.js to function. There is already a
placeholder method
+for all API calls as specified in the ECMAScript specification and is present
in all
+JavaScript engines, so when l10n.js isn't present, your application works fine.
+
+
+Demo
+----
+
+You can try out the [online demo][1] to see l10n.js in action.
+
+Currently the demo only supports the following locales.
+
+* [English](http://purl.eligrey.com/l10n.js/demo/en)
+ * [American English](http://purl.eligrey.com/l10n.js/demo/en-US)
+ * [American Hixie
English](http://purl.eligrey.com/l10n.js/demo/en-US-x-Hixie)
+ * [British English](http://purl.eligrey.com/l10n.js/demo/en-GB)
+ * [British Hixie
English](http://purl.eligrey.com/l10n.js/demo/en-GB-x-Hixie)
+ * [Canadian English](http://purl.eligrey.com/l10n.js/demo/en-CA)
+ * [Australian English](http://purl.eligrey.com/l10n.js/demo/en-AU)
+* [Portuguese](http://purl.eligrey.com/l10n.js/demo/pt)
+* [Spanish](http://purl.eligrey.com/l10n.js/demo/es)
+* [French](http://purl.eligrey.com/l10n.js/demo/fr)
+
+If you know a language that isn't currently supported in the demo, I encourage
you to
+contribute a localization by sending me your own localizations, either
[through GitHub][2]
+or [directly][3]. The following strings would need to be localized:
+
+* `l10n.js demo` to `{Locale} - l10n.js demo` in the locale.
+* `You are viewing the original page locale.` to `You are viewing a {locale}
localization
+ of this page.` in the locale.
+* `en` to the locale's language code.
+* Optionally, `ltr` to `rtl` if the locale uses right-to-left directionality.
+
+ [1]: http://purl.eligrey.com/l10n.js/demo
+ [2]: http://github.com/inbox/new/eligrey
+ [3]: http://purl.eligrey.com/contact
+
+
+Supported Browsers
+------------------
+
+* Internet Explorer 5+
+* Firefox 2+
+* Opera 9+
+ * Doesn't support region-specific locales. Only gives "en" in the case of
"en-US".
+* Google Chrome 1+
+* Safari 4+
+
+
+Getting Started
+---------------
+
+ 1. [Download l10n.js][4].
+ 2. Localize strings used in your JavaScript application. See the [demo
localizations
+ file][5] for an example localizations file. You can also specify external
+ localizations in your main localizations file by assigning a URL string to
a language
+ code, such as `"en-us": "localizations/en-us.json"`.
+ 3. Include the appropriate link elements, as described in the usage section,
anywhere in
+ your document. I recommend putting it in the document's `<head>`.
+ 4. Place `<script type="text/javascript" src="path/to/l10n.js"></script>`
+ anywhere after the `<link>` tag.
+ 5. Call `toLocaleString()` on any strings you wish to localize.
+
+
+ [4]: http://purl.eligrey.com/github/l10n.js/raw/master/l10n.js
+ [5]:
http://purl.eligrey.com/github/l10n.js/blob/master/demo/localizations.json
+
+
+Usage
+-----
+
+### Localizing strings
+
+Calling `toLocaleString()` on every localizable string can create a lot of
extra typing
+and bloat for sending your JavaScript down the wire. I recommend using the
following
+helper function to localize strings. The reason I don't define this in l10n.js
is to not
+introduce any new globals, which keeps l10n.js a one of the JavaScript
libraries
+least-prone to conflicts with other libraries.
+
+ var l = function (string) {
+ return string.toLocaleString();
+ };
+
+With this helper function, you can start writing `l("Your localizable
string")` instead
+of `"Your localizable string".toLocaleString()`. I chose `l` instead of `_` (an
+underscore), because it's easier to spot so you can quickly skim your code to
see which
+strings are localizable.
+
+
+### Variable replacement
+
+If you don't mind requiring l10n.js for your JavaScript application or library
to
+function, I suggest using short variable strings instead of default strings.
It saves
+bandwidth by decreasing the size of localization files, and it enables you to
write
+nice, short code as such in the following.
+
+* `document.title = l("%title.search")`
+ * Example results: `"Seach - Acme, Inc."`
+* `confirm(l("%confirm.deleteAccount"))`
+ * Example results: `"Are you sure you want to delete your account?"`
+* `link.href = "http://www.google." + l("%locale.tld")`
+ * Example results: `"http://www.google.co.uk"`
+
+Often, string concatenation is used instead of replacement in JavaScript. With
l10n.js,
+to make localization easier, you may have to use replacements instead. You
might want to
+use a JavaScript library that implements something similar to C++'s
`sprintf()`. A nice
+JavaScript implementation I'd recommend is [php.js's `sprintf()`][4].
+
+ [4]: http://phpjs.org/functions/sprintf
+
+
+### When localizations are downloaded
+
+If you are using single localization URLs
+(`<link rel="localization" hreflang="..." href="..."
type="application/x-l10n+json"/>`),
+they will only be downloaded when needed. If you are using multiple
localizations in one
+(`<link rel="localizations" href="..." type="application/x-l10n+json"/>`),
then the file
+will be downloaded right away, but externally linked localizations in the
localization
+file will not be. If you provide an interface for your users to change
locales, any
+non-loaded localization files will be loaded when necessary.
+
+
+### Including localizations with link elements
+
+Multiple localizations can be included with one localization JSON file, with
all of the
+top properties being language codes. Instead of putting all of the localized
strings
+directly in the file, you may want to assign a specifc localization JSON URL
to each
+locale, as to save bandwidth by only downloading locales the user needs.
+
+The following is an example localization file for
+`<link rel="localizations" href="path/to/localizations.json"
type="application/x-l10n+json"/>`.
+
+ {
+ "en-US": {
+ "What is your favourite colour?": "What is your favorite color?"
+ },
+ "fr": "path/to/french-localization.json"
+ }
+
+Using localization files is the same as calling `String.toLocaleString()`
witht the JSON
+localizations object as the first parameter.
+
+You can also include single localizations by specifying the standard HTML5
`hreflang` link
+element attribute and using a rel of `localization` instead of `localizations`
with an
+'s', as shown in the following.
+
+ <link rel="localization" hreflang="en-US" href="american-english.json"
type="application/x-l10n+json"/>
+
+The JSON file for the localization might look like the following.
+
+ {
+ "What is your favourite colour?": "What is your favorite color?"
+ }
+
+
+API
+---
+
+Strong and emphasized text has titles (which can be viewed by hovering your
cursor over
+them) containing their type if they are not functions or return type if they
are.
+
+
+### Methods
+
+<dl>
+ <dt><code>String.<strong title="String">toLocaleString</strong>([<strong
title="Object or String or Boolean">localizations</strong>])</code></dt>
+ <dd>
+ If <code title="Object">localizations</code> is an object, it is added to
the
+ localizations.
+ <br />
+ If <code title="String">localizations</code> is a string, it is requested
as JSON and
+ then added to the localizations.
+ <br />
+ If <code title="Boolean">localizations</code> is <code>false</code>, then
all
+ localizations are reset.
+ <br />
+ If <code title="Object">localizations</code> is an object, and a locale is
+ <code>false</code>, then all localizations for that locale are reset.
+ <p>
+ The string representation of the <code>String</code> contructor is
returned, to
+ maintain backwards compatibility with any code using this method to
actually get it.
+ </p>
+
+ <h4>Examples</h4>
+ <ul>
+ <li>
+ Loading a localizations JSON file:
+ <pre><code>String.toLocaleString(<strong
title="String">"path/to/localizations.json"</strong>)</code></pre>
+ </li>
+ <li>
+ Defining localizations directly:
+ <p>
+ The nearest locale to the user's locale that has the string being
localized is
+ used in localization.
+ </p>
+ <pre><code>String.toLocaleString({
+ "es": { // Spanish
+ "Hello, world!": "¡Hola, mundo!"
+ // more localizations...
+ },
+ "en-US": { // American English
+ "Hello, world!": "Hello, America!" // Locale-specific message
+ // more localizations...
+ },
+ "en-GB": false, // resetting British English localizations
+ // Specifying external localization JSON for Japanese:
+ // The URL isn't requested unless the user's locale is Japanese
+ "jp": "localizations/jp.json"
+})</code></pre>
+ </li>
+ <li>
+ Resetting all localizations:
+ <pre><code>String.toLocaleString(<strong
title="Boolean">false</strong>)</code></pre>
+ </li>
+ </ul>
+ </dd>
+
+ <dt><code>aString.<strong
title="String">toLocaleString</strong>()</strong></code></dt>
+ <dd>
+ Returns the localized version of <code>aString</code> in the user's locale,
+ if available. Otherwise, it returns the same string.
+ </dd>
+</dl>
+
+### Fields
+
+<dl>
+ <dt><code>String.<strong title="Object">locale</strong></code></dt>
+ <dd>
+ A configurable string which represents the language code of the locale to
use for
+ localization. It defaults to the user's own locale.
+ </dd>
+</dl>
+
+
+
Added:
plugins/ncJavascriptLocalizationPlugin/config/ncJavascriptLocalizationPluginConfiguration.class.php
===================================================================
---
plugins/ncJavascriptLocalizationPlugin/config/ncJavascriptLocalizationPluginConfiguration.class.php
(rev 0)
+++
plugins/ncJavascriptLocalizationPlugin/config/ncJavascriptLocalizationPluginConfiguration.class.php
2010-05-13 18:08:07 UTC (rev 29438)
@@ -0,0 +1,13 @@
+<?php
+
+class ncJavascriptLocalizationPluginConfiguration extends sfPluginConfiguration
+{
+ public function initialize()
+ {
+ if (sfConfig::get('app_nc_js_l10n_routes_register', true) &&
in_array('nc_js_l10n', sfConfig::get('sf_enabled_modules', array())))
+ {
+ $this->dispatcher->connect('routing.load_configuration',
array('ncJSL10NRouting', 'routing_load_configurationEventListener'));
+ }
+ }
+}
+
Added: plugins/ncJavascriptLocalizationPlugin/lib/helper/ncJSL10NHelper.php
===================================================================
--- plugins/ncJavascriptLocalizationPlugin/lib/helper/ncJSL10NHelper.php
(rev 0)
+++ plugins/ncJavascriptLocalizationPlugin/lib/helper/ncJSL10NHelper.php
2010-05-13 18:08:07 UTC (rev 29438)
@@ -0,0 +1,78 @@
+<?php
+
+/**
+ * ncJSL10NHelper
+ *
+ * Helper class for including Javascript Localization files into the response.
+ *
+ * @package symfony
+ * @subpackage plugin
+ * @author José Nahuel Cuesta Luengo <[email protected]>
+ * @version SVN: $Id$
+ */
+
+function include_js_l10n_json($languages = null)
+{
+ $context = sfContext::getInstance();
+ $use_i18n = sfConfig::get('sf_i18n');
+
+ if (!$use_i18n)
+ {
+ return false;
+ }
+
+ $i18n = $use_i18n ? $context->getI18N() : null;
+
+ if (is_null($languages))
+ {
+ $languages = array($context->getUser()->getCulture());
+ }
+ elseif (!is_array($languages))
+ {
+ $languages = array($languages);
+ }
+
+ foreach ($languages as $language)
+ {
+ echo tag('link', array('rel' => 'localizations', 'type' =>
'application/x-l10n+json', 'href' =>
url_for(_get_nc_js_l10n_route($language))));
+ }
+
+ if (sfConfig::get('app_nc_js_l10n_language_set_sf_culture_for_js', false))
+ {
+ echo _get_nc_js_l10n_sf_culture_setter();
+ }
+
+ return true;
+}
+
+function _get_nc_js_l10n_route($language)
+{
+ if (sfConfig::get('app_nc_js_l10n_routes_register', true) &&
in_array('nc_js_l10n', sfConfig::get('sf_enabled_modules', array())))
+ {
+ return '@nc_js_l10n_json?language='.$language;
+ }
+ elseif (sfConfig::get('app_nc_js_l10n_routes_register', true))
+ {
+ // The default module is disabled. No can do!
+ return '';
+ }
+ else
+ {
+ $route = sfConfig::get('app_nc_js_l10n_routes_custom_route_name');
+ $parameter_name =
sfConfig::get('app_nc_js_l10n_router_custom_route_param_name', 'language');
+
+ return array('sf_route' => $route, $parameter_name => $language);
+ }
+}
+
+function _get_nc_js_l10n_sf_culture_setter()
+{
+ return sprintf(<<<EOF
+<script type="text/javascript">
+ String.locale = '%s';
+</script>
+EOF
+ ,
+ str_replace('_', '-', sfContext::getInstance()->getUser()->getCulture())
+ );
+}
\ No newline at end of file
Property changes on:
plugins/ncJavascriptLocalizationPlugin/lib/helper/ncJSL10NHelper.php
___________________________________________________________________
Added: svn:keywords
+ Id
Added: plugins/ncJavascriptLocalizationPlugin/lib/l10n/ncJSL10N.class.php
===================================================================
--- plugins/ncJavascriptLocalizationPlugin/lib/l10n/ncJSL10N.class.php
(rev 0)
+++ plugins/ncJavascriptLocalizationPlugin/lib/l10n/ncJSL10N.class.php
2010-05-13 18:08:07 UTC (rev 29438)
@@ -0,0 +1,148 @@
+<?php
+
+/**
+ * ncJSL10N
+ *
+ * @package symfony
+ * @subpackage plugin
+ * @author José Nahuel Cuesta Luengo <[email protected]>
+ * @version SVN: $Id$
+ */
+class ncJSL10N
+{
+ static protected $_instance;
+
+ protected
+ $i18n,
+ $catalogue;
+
+ /**
+ * Return this class unique instance.
+ * Singleton implementation.
+ *
+ * @param sfContext $context The context
+ *
+ * @return ncJSL10N The instance
+ */
+ static public function getInstance(sfContext $context = null)
+ {
+ if (is_null(self::$_instance))
+ {
+ $i18n = is_null($context) ? sfContext::getInstance()->getI18N() :
$context->getI18N();
+
+ self::$_instance = new self($i18n, $context);
+ }
+
+ return self::$_instance;
+ }
+
+ /**
+ * Constructor
+ *
+ * @param sfI18N $i18n
+ * @param sfContext $context
+ */
+ public function __construct(sfI18N $i18n, sfContext $context = null)
+ {
+ $this->i18n = $i18n;
+ $this->catalogue = sfConfig::get('app_nc_js_l10n_catalogue', 'nc_js_l10n');
+ $this->context = is_null($context) ? sfContext::getInstance() : $context;
+ }
+
+ /**
+ * Get the localization dictionary.
+ * The generated dictionary will be a decomposition
+ * of the culture. That is, if the culture is 'en_US',
+ * the resulting dictionary will be:
+ *
+ * {
+ * "en-us": {
+ * // ... localized messages
+ * },
+ * "en": {
+ * // ... localized messages
+ * }
+ * }
+ *
+ * @param string $culture The target culture
+ *
+ * @return string The dictionary as a JSON object
+ */
+ public function getDictionary($culture)
+ {
+ $dictionary = '{}';
+ $culture = strtolower($culture);
+
+ $old_culture = $this->getI18N()->getCulture();
+
+ $this->getI18N()->setCulture($culture);
+
+ if ($this->loadCatalogue())
+ {
+ $dictionary = array();
+ $offset = 0;
+
+ while ($culture)
+ {
+ $dictionary[] = sprintf('"%s": { %s }', str_replace('_', '-',
$culture), $this->flatten($this->getI18N()->getMessageSource()->read()));
+
+ if (false !== strrpos($culture, '_'))
+ {
+ $culture = substr($culture, 0, strrpos($culture, '_'));
+ }
+ else
+ {
+ $culture = false;
+ }
+ }
+
+ $dictionary = sprintf('{ %s }', implode(', ', $dictionary));
+ }
+
+ $this->getI18N()->setCulture($old_culture);
+
+ return $dictionary;
+ }
+
+ /**
+ * Flatten an input array of messages in order to have it
+ * as a uni-dimensional array.
+ *
+ * @param array $messages
+ *
+ * @return string The flattened array as JSON
+ */
+ protected function flatten($messages = array())
+ {
+ $json = array();
+ $messages = array_shift($messages);
+
+ foreach ($messages as $source => $translation)
+ {
+ $json[] = sprintf('"%s": "%s"', $source, $translation[0]);
+ }
+
+ return implode(', ', $json);
+ }
+
+ /**
+ * Try to load the catalogue.
+ * Return TRUE on success, or FALSE on failure.
+ *
+ * @return Boolean True if the catalog could be loaded
+ */
+ protected function loadCatalogue()
+ {
+ return $this->getI18N()->getMessageSource()->load($this->catalogue);
+ }
+
+ /**
+ * Get inner i18n instance.
+ *
+ * @return sfI18n
+ */
+ public function getI18N()
+ {
+ return $this->i18n;
+ }
+}
\ No newline at end of file
Added:
plugins/ncJavascriptLocalizationPlugin/lib/routing/ncJSL10NRouting.class.php
===================================================================
---
plugins/ncJavascriptLocalizationPlugin/lib/routing/ncJSL10NRouting.class.php
(rev 0)
+++
plugins/ncJavascriptLocalizationPlugin/lib/routing/ncJSL10NRouting.class.php
2010-05-13 18:08:07 UTC (rev 29438)
@@ -0,0 +1,22 @@
+<?php
+
+/**
+ * ncJSL10NRouting
+ *
+ * @package symfony
+ * @subpackage plugin
+ * @author José Nahuel Cuesta Luengo <[email protected]>
+ * @version SVN: $Id$
+ */
+class ncJSL10NRouting
+{
+ /**
+ * Event listener for `routing.load_configuration' event.
+ *
+ * @param sfEvent The event itself
+ */
+ static public function routing_load_configurationEventListener(sfEvent
$event)
+ {
+ $event->getSubject()->prependRoute('nc_js_l10n_json', new
sfRoute('/nc_js_l10n/:language.json', array('module' => 'nc_js_l10n', 'action'
=> 'json')));
+ }
+}
Property changes on:
plugins/ncJavascriptLocalizationPlugin/lib/routing/ncJSL10NRouting.class.php
___________________________________________________________________
Added: svn:keywords
+ Id
Added:
plugins/ncJavascriptLocalizationPlugin/modules/nc_js_l10n/actions/actions.class.php
===================================================================
---
plugins/ncJavascriptLocalizationPlugin/modules/nc_js_l10n/actions/actions.class.php
(rev 0)
+++
plugins/ncJavascriptLocalizationPlugin/modules/nc_js_l10n/actions/actions.class.php
2010-05-13 18:08:07 UTC (rev 29438)
@@ -0,0 +1,16 @@
+<?php
+
+// Require base actions
+require_once(dirname(__FILE__).'/../lib/BasencJSL10NActions.class.php');
+
+/**
+ * ncJSL10NActions
+ *
+ * @package symfony
+ * @subpackage plugin
+ * @author José Nahuel Cuesta Luengo <[email protected]>
+ * @version SVN: $Id$
+ */
+class nc_js_l10nActions extends BasencJSL10NActions
+{
+}
Property changes on:
plugins/ncJavascriptLocalizationPlugin/modules/nc_js_l10n/actions/actions.class.php
___________________________________________________________________
Added: svn:keywords
+ Id
Added:
plugins/ncJavascriptLocalizationPlugin/modules/nc_js_l10n/lib/BasencJSL10NActions.class.php
===================================================================
---
plugins/ncJavascriptLocalizationPlugin/modules/nc_js_l10n/lib/BasencJSL10NActions.class.php
(rev 0)
+++
plugins/ncJavascriptLocalizationPlugin/modules/nc_js_l10n/lib/BasencJSL10NActions.class.php
2010-05-13 18:08:07 UTC (rev 29438)
@@ -0,0 +1,25 @@
+<?php
+
+/**
+ * BasencJSL10NActions
+ *
+ * @package symfony
+ * @subpackage plugin
+ * @author José Nahuel Cuesta Luengo <[email protected]>
+ * @version SVN: $Id$
+ */
+class BasencJSL10NActions extends sfActions
+{
+ public function executeJson(sfWebRequest $request)
+ {
+ $this->getResponse()->setContentType('application/json');
+
+ $parameter = sfConfig::get('app_nc_js_l10n_routes_register', true) ?
'language' : sfConfig::get('app_nc_js_l10n_routes_custom_route_param_name',
'language');
+ $language = $request->getParameter($parameter,
sfConfig::get('app_nc_js_l10n_language_default',
$this->getUser()->getCulture()));
+ $catalogue = sfConfig::get('app_nc_js_l10n_catalogue', 'nc_js_l10n');
+
+ $dictionary =
ncJSL10N::getInstance($this->getContext())->getDictionary($language);
+
+ return $this->renderText($dictionary);
+ }
+}
Property changes on:
plugins/ncJavascriptLocalizationPlugin/modules/nc_js_l10n/lib/BasencJSL10NActions.class.php
___________________________________________________________________
Added: svn:keywords
+ Id
Added: plugins/ncJavascriptLocalizationPlugin/web/js/global.js
===================================================================
--- plugins/ncJavascriptLocalizationPlugin/web/js/global.js
(rev 0)
+++ plugins/ncJavascriptLocalizationPlugin/web/js/global.js 2010-05-13
18:08:07 UTC (rev 29438)
@@ -0,0 +1,20 @@
+/**
+ * global.js
+ *
+ * This file introduces a global function
+ * that is the JS-equivalent of sfI18N's __() function.
+ *
+ * @package symfony
+ * @subpackage plugin
+ * @author José Nahuel Cuesta Luengo <[email protected]>
+ * @version SVN: $Id$
+ */
+
+// Declare the '__' global function.
+// Then, every string can be localized by passing it as a
+// parameter to this function,
+// i.e.
+// alert(__('My localized string'));
+var __ = function (input) {
+ return input.toLocaleString();
+}
\ No newline at end of file
Property changes on: plugins/ncJavascriptLocalizationPlugin/web/js/global.js
___________________________________________________________________
Added: svn:keywords
+ Id
Added: plugins/ncJavascriptLocalizationPlugin/web/js/l10n.js
===================================================================
--- plugins/ncJavascriptLocalizationPlugin/web/js/l10n.js
(rev 0)
+++ plugins/ncJavascriptLocalizationPlugin/web/js/l10n.js 2010-05-13
18:08:07 UTC (rev 29438)
@@ -0,0 +1,189 @@
+/*
+ * l10n.js
+ * Version 0.1
+ *
+ * 2010-05-09
+ *
+ * By Elijah Grey, http://eligrey.com
+ *
+ * License: GNU GPL v3 and the X11/MIT license
+ * See COPYING.md
+ */
+
+/*global XMLHttpRequest, setTimeout, document, navigator, ActiveXObject*/
+
+/*jslint white: true, undef: true, nomen: true, eqeqeq: true, bitwise: true,
regexp: true,
+newcap: true, immed: true, maxlen: 90, indent: 4 */
+
+"use strict";
+
+(function (String) {
+ var undefType = "undefined",
+ stringType = "string",
+ hasOwnProp = Object.prototype.hasOwnProperty,
+ loadQueues = {},
+ localeCache = {},
+ localizations = {},
+ False = !1,
+ XHR,
+
+ getLocale = function (locale) {
+ // replace -x- for cases like en-US-x-hixie and en-US-hixie
which are equivalent
+ // also memoize the results for each locale
+ return localeCache[locale] ||
+ (localeCache[locale] =
locale.toLowerCase().replace(/-x-/g, "-"));
+ },
+ requestJSON = function (uri) {
+ var req = new XHR();
+
+ // sadly, this has to be blocking to allow for a graceful
degrading API
+ req.open("GET", uri, False);
+ req.send(null);
+
+ if (req.status !== 200) {
+ // warn about error without stopping execution
+ setTimeout(function () {
+ // Error messages are not localized as not to
cause an infinite loop
+ var l10nErr = new Error("Unable to load
localization data: " + uri);
+ l10nErr.name = "Localization Error";
+ throw l10nErr;
+ }, 0);
+
+ return {};
+ } else {
+ return JSON.parse(req.responseText);
+ }
+ },
+ load = String.toLocaleString = function (data) {
+ if (arguments.length > 0 && typeof data !== "number") {
+ if (typeof data === stringType) {
+ load(requestJSON(data));
+ } else if (data === False) {
+ // reset all localizations
+ localizations = {};
+ } else {
+ // Extend current localizations instead of
completely overwriting them
+ for (var locale in data) {
+ if (hasOwnProp.call(data, locale)) {
+ var localization = data[locale];
+ locale = getLocale(locale);
+
+ if (!(locale in localizations)
|| localization === False) {
+ // reset locale if not
existing or reset flag is specified
+ localizations[locale] =
{};
+ }
+
+ if (localization === False) {
+ continue;
+ }
+
+ // URL specified
+ if (typeof localization ===
stringType) {
+ if
(getLocale(String.locale).indexOf(locale) === 0) {
+ localization =
requestJSON(localization);
+ } else {
+ // queue
loading locale if not needed
+ if (!(locale in
loadQueues)) {
+
loadQueues[locale] = [];
+ }
+
loadQueues[locale].push(localization);
+ continue;
+ }
+ }
+
+ for (var message in
localization) {
+ if
(hasOwnProp.call(localization, message)) {
+
localizations[locale][message] = localization[message];
+ }
+ }
+ }
+ }
+ }
+ }
+ // Return what function.toLocaleString() normally returns
+ return Function.prototype.toLocaleString.apply(String,
arguments);
+ },
+ processLoadQueue = function (locale) {
+ var queue = loadQueues[locale],
+ i = 0,
+ len = queue.length;
+
+ for (; i < len; i++) {
+ var localization = {};
+ localization[locale] = requestJSON(queue[i]);
+ load(localization);
+ }
+
+ delete loadQueues[locale];
+ };
+
+ if (typeof XMLHttpRequest === undefType && typeof ActiveXObject !==
undefType) {
+ var AXO = ActiveXObject;
+
+ XHR = function () {
+ try {
+ return new AXO("Msxml2.XMLHTTP.6.0");
+ } catch (xhrEx1) {}
+ try {
+ return new AXO("Msxml2.XMLHTTP.3.0");
+ } catch (xhrEx2) {}
+ try {
+ return new AXO("Msxml2.XMLHTTP");
+ } catch (xhrEx3) {}
+
+ throw new Error("XMLHttpRequest not supported by this
browser.");
+ };
+ } else {
+ XHR = XMLHttpRequest;
+ }
+
+ if (!String.locale) {
+ if (typeof navigator !== undefType) {
+ var nav = navigator;
+ String.locale = nav.language || nav.userLanguage || "";
+ } else {
+ String.locale = "";
+ }
+ }
+
+ if (typeof document !== undefType) {
+ var linkElems = document.getElementsByTagName("link"),
+ i = linkElems.length;
+
+ while (i--) {
+ var linkElem = linkElems[i],
+ relList = (linkElem.getAttribute("rel") ||
"").toLowerCase().split(/\s+/);
+
+ // multiple localizations
+ if (relList.indexOf("localizations") !== -1) {
+ load(linkElem.getAttribute("href"));
+ } else if (relList.indexOf("localization") !== -1) {
+ // single localization
+ var localization = {};
+
localization[getLocale(linkElem.getAttribute("hreflang") || "")] =
+ linkElem.getAttribute("href");
+ load(localization);
+ }
+ }
+ }
+
+ String.prototype.toLocaleString = function () {
+ var parts = getLocale(String.locale).split("-"),
+ i = parts.length,
+ thisValue = this.valueOf();
+
+ // Iterate through locales starting at most-specific until
localization is found
+ while (i) {
+ var locale = parts.slice(0, i--).join("-");
+ // load locale if not loaded
+ if (locale in loadQueues) {
+ processLoadQueue(locale);
+ }
+ if (locale in localizations && thisValue in
localizations[locale]) {
+ return localizations[locale][thisValue];
+ }
+ }
+
+ return thisValue;
+ };
+}(String));
Added: plugins/ncJavascriptLocalizationPlugin/web/js/l10n.min.js
===================================================================
--- plugins/ncJavascriptLocalizationPlugin/web/js/l10n.min.js
(rev 0)
+++ plugins/ncJavascriptLocalizationPlugin/web/js/l10n.min.js 2010-05-13
18:08:07 UTC (rev 29438)
@@ -0,0 +1,2 @@
+//@source http://purl.eligrey.com/github/l10n.js/blob/master/l10n.js
+"use strict";(function(s){var
u="undefined",l="string",q=Object.prototype.hasOwnProperty,f={},r={},t={},k=!1,m,n=function(i){return
r[i]||(r[i]=i.toLowerCase().replace(/-x-/g,"-"))},p=function(v){var i=new
m();i.open("GET",v,k);i.send(null);if(i.status!==200){setTimeout(function(){var
w=new Error("Unable to load localization data: "+v);w.name="Localization
Error";throw w},0);return{}}else{return
JSON.parse(i.responseText)}},j=s.toLocaleString=function(w){if(arguments.length>0&&typeof
w!=="number"){if(typeof w===l){j(p(w))}else{if(w===k){t={}}else{for(var i in
w){if(q.call(w,i)){var x=w[i];i=n(i);if(!(i in
t)||x===k){t[i]={}}if(x===k){continue}if(typeof
x===l){if(n(s.locale).indexOf(i)===0){x=p(x)}else{if(!(i in
f)){f[i]=[]}f[i].push(x);continue}}for(var v in
x){if(q.call(x,v)){t[i][v]=x[v]}}}}}}}return
Function.prototype.toLocaleString.apply(s,arguments)},a=function(x){var
w=f[x],y=0,v=w.length;for(;y<v;y++){var z={};z[x]=p(w[y]);j(z)}delete
f[x]};if(typeof XMLHttpRequest===u&&typeof ActiveXObject!==u){var
d=ActiveXObject;m=function(){try{return new
d("Msxml2.XMLHTTP.6.0")}catch(v){}try{return new
d("Msxml2.XMLHTTP.3.0")}catch(i){}try{return new
d("Msxml2.XMLHTTP")}catch(w){}throw new Error("XMLHttpRequest not supported by
this browser.")}}else{m=XMLHttpRequest}if(!s.locale){if(typeof
navigator!==u){var
h=navigator;s.locale=h.language||h.userLanguage||""}else{s.locale=""}}if(typeof
document!==u){var
b=document.getElementsByTagName("link"),o=b.length;while(o--){var
e=b[o],c=(e.getAttribute("rel")||"").toLowerCase().split(/\s+/);if(c.indexOf("localizations")!==-1){j(e.getAttribute("href"))}else{if(c.indexOf("localization")!==-1){var
g={};g[n(e.getAttribute("hreflang")||"")]=e.getAttribute("href");j(g)}}}}s.prototype.toLocaleString=function(){var
y=n(s.locale).split("-"),x=y.length,w=this.valueOf();while(x){var
v=y.slice(0,x--).join("-");if(v in f){a(v)}if(v in t&&w in t[v]){return
t[v][w]}}return w}}(String));
--
You received this message because you are subscribed to the Google Groups
"symfony SVN" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to
[email protected].
For more options, visit this group at
http://groups.google.com/group/symfony-svn?hl=en.