CRM-14949 - Move localization strings into a dynamic js tpl
authorColeman Watts <coleman@civicrm.org>
Sun, 6 Jul 2014 17:35:03 +0000 (18:35 +0100)
committerColeman Watts <coleman@civicrm.org>
Wed, 9 Jul 2014 14:08:35 +0000 (15:08 +0100)
CRM/Admin/Page/AJAX.php
CRM/Core/Page/AJAX.php
CRM/Core/Resources.php
CRM/Core/xml/Menu/Misc.xml
js/Common.js
js/crm.ajax.js
templates/CRM/Form/validate.js.tpl [new file with mode: 0644]
templates/CRM/Form/validate.tpl

index d036198457a0c13065aa4053402fcc661e6a3ce3..844f61441770f59d4c385f3fd3ed7af8ea209f12 100644 (file)
@@ -43,22 +43,11 @@ class CRM_Admin_Page_AJAX {
    * @see smarty_function_crmNavigationMenu
    */
   static function getNavigationMenu() {
-    $session = CRM_Core_Session::singleton();
-    $contactID = $session->get('userID');
+    $contactID = CRM_Core_Session::singleton()->get('userID');
     if ($contactID) {
-      // Set headers to encourage browsers to cache for a long time
-      // If we want to refresh the menu we will send a different url
-      $year = 60*60*24*364;
-      header('Expires: '.gmdate('D, d M Y H:i:s \G\M\T', time() + $year));
-      header('Content-Type:    application/javascript');
-      header("Cache-Control: max-age=$year, public");
-
-      // Render template as a javascript file
-      $smarty = CRM_Core_Smarty::singleton();
-      $navigation = CRM_Core_BAO_Navigation::createNavigation($contactID);
-      $smarty->assign('timeGenerated', date('d M Y H:i:s'));
-      $smarty->assign('navigation', $navigation);
-      print $smarty->fetch('CRM/common/navigation.js.tpl');
+      CRM_Core_Page_AJAX::returnDynamicJS('CRM/common/navigation.js.tpl', array(
+        'navigation' => CRM_Core_BAO_Navigation::createNavigation($contactID),
+      ));
     }
     CRM_Utils_System::civiExit();
   }
index 593beb5f3cc3a4569db118827e07f68e6f77cfb3..dbbd257cb0f72b969e1b02de9f120916ceb28ee8 100644 (file)
@@ -199,6 +199,27 @@ class CRM_Core_Page_AJAX {
     CRM_Utils_System::civiExit();
   }
 
+  /**
+   * Render and output a template as a javascript file
+   * @param string $tplFile
+   * @param array $vars - template variables
+   */
+  static function returnDynamicJS($tplFile, $vars = array()) {
+    // Set headers to encourage browsers to cache for a long time
+    $year = 60*60*24*364;
+    header('Expires: '.gmdate('D, d M Y H:i:s \G\M\T', time() + $year));
+    header('Content-Type:      application/javascript');
+    header("Cache-Control: max-age=$year, public");
+
+    $smarty = CRM_Core_Smarty::singleton();
+    $vars += array('timeGenerated' => date('d M Y H:i:s'));
+    foreach ($vars as $name => $val) {
+      $smarty->assign($name, $val);
+    }
+    print $smarty->fetch($tplFile);
+    CRM_Utils_System::civiExit();
+  }
+
   /**
    * Send autocomplete results to the client. Input can be a simple or nested array.
    * @param array $results - If nested array, also provide:
index 9064f1a54d5761c0f2259f49033f56034fe92574..66332cf1afe7765036598daee434842e4fb79e48 100644 (file)
@@ -467,14 +467,6 @@ class CRM_Core_Resources {
         }
       }
 
-      // Initialize CRM.url and CRM.formatMoney
-      $url = CRM_Utils_System::url('civicrm/example', 'placeholder', FALSE, NULL, FALSE);
-      $js = "CRM.url('init', '$url');\n";
-      $js .= "CRM.formatMoney('init', " . json_encode(CRM_Utils_Money::format(1234.56)) . ");";
-
-      $this->addLocalization($js);
-      $this->addScript($js, $jsWeight++, $region);
-
       // Add global settings
       $settings = array(
         'userFramework' => $config->userFramework,
@@ -484,7 +476,15 @@ class CRM_Core_Resources {
       );
       $this->addSetting(array('config' => $settings));
 
-      // Give control of jQuery back to the CMS - this loads last
+      // Contact create profiles with localized names
+      if (CRM_Core_Permission::check('edit all contacts') || CRM_Core_Permission::check('add contacts')) {
+        $this->addSetting(array('profile' => array('contactCreate' => CRM_Core_BAO_UFGroup::getCreateLinks())));
+      }
+
+      // Add dynamic localization script
+      $this->addScriptUrl(CRM_Utils_System::url('civicrm/ajax/localizationjs/' . $config->lcMessages), $jsWeight++, $region);
+
+      // Give control of jQuery and _ back to the CMS - this loads last
       $this->addScriptFile('civicrm', 'js/noconflict.js', 9999, $region, FALSE);
 
       $this->addCoreStyles($region);
@@ -551,26 +551,16 @@ class CRM_Core_Resources {
   }
 
   /**
-   * Add inline scripts needed to localize js widgets
-   * @param string $js
+   * Callback to add dymanic script for localizing js widgets
    */
-  function addLocalization(&$js) {
+  static function outputLocalizationJS() {
     $config = CRM_Core_Config::singleton();
-
-    // Localize select2 strings
-    $contactSearch = json_encode($config->includeEmailInName ? ts('Start typing a name or email...') : ts('Start typing a name...'));
-    $otherSearch = json_encode(ts('Enter search term...'));
-    $js .= "
-      $.fn.select2.defaults.formatNoMatches = " . json_encode(ts("None found.")) . ";
-      $.fn.select2.defaults.formatLoadMore = " . json_encode(ts("Loading...")) . ";
-      $.fn.select2.defaults.formatSearching = " . json_encode(ts("Searching...")) . ";
-      $.fn.select2.defaults.formatInputTooShort = function(){return CRM.$(this).data('api-entity') == 'contact' ? $contactSearch : $otherSearch};
-    ";
-
-    // Contact create profiles with localized names
-    if (CRM_Core_Permission::check('edit all contacts') || CRM_Core_Permission::check('add contacts')) {
-      $this->addSetting(array('profile' => array('contactCreate' => CRM_Core_BAO_UFGroup::getCreateLinks())));
-    }
+    $vars = array(
+      'moneyFormat' => json_encode(CRM_Utils_Money::format(1234.56)),
+      'contactSearch' => json_encode($config->includeEmailInName ? ts('Start typing a name or email...') : ts('Start typing a name...')),
+      'otherSearch' => json_encode(ts('Enter search term...')),
+    );
+    CRM_Core_Page_AJAX::returnDynamicJS('CRM/Form/validate.js.tpl', $vars);
   }
 
   /**
index e1f4a1d11d43694c01890bdc8514851933ac1a95..020ff717f5c8c6a366563d2e497f84975c1735f8 100644 (file)
     <page_callback>CRM_Core_Page_Angular</page_callback>
     <access_arguments>access CiviCRM</access_arguments>
   </item>
+  <item>
+    <path>civicrm/ajax/localizationjs</path>
+    <page_callback>CRM_Core_Resources::outputLocalizationJS</page_callback>
+  </item>
 </menu>
index fa3c91072277a6456d514eddcc243964ff84e882..3f8beae7571e7a814d167f9160c0706be98ecbb2 100644 (file)
@@ -195,10 +195,6 @@ function showHideRow(index) {
 
 CRM.utils = CRM.utils || {};
 CRM.strings = CRM.strings || {};
-CRM.validate = CRM.validate || {
-  params: {},
-  functions: []
-};
 
 (function ($, _, undefined) {
   "use strict";
@@ -481,6 +477,24 @@ CRM.validate = CRM.validate || {
     return markup;
   }
 
+  /**
+   * Wrapper for jQuery validate initialization function; supplies defaults
+   * @param options object
+   */
+  $.fn.crmValidate = function(params) {
+    return $(this).each(function () {
+      var that = this,
+        settings = $.extend({}, CRM.validate._defaults, CRM.validate.params);
+      $(this).validate(settings);
+      // Call any post-initialization callbacks
+      if (CRM.validate.functions && CRM.validate.functions.length) {
+        $.each(CRM.validate.functions, function(i, func) {
+          func.call(that);
+        });
+      }
+    });
+  }
+
   // Initialize widgets
   $(document)
     .on('crmLoad', function(e) {
index a3e9932e6e0ebd4c98f2ee77022cba9e40117f52..b647e370c8bfd5a604da392944e2c9e3211b4b1a 100644 (file)
         }
       });
       if (settings.validate) {
-        $("form", this).validate(typeof(settings.validate) == 'object' ? settings.validate : CRM.validate.params);
+        $("form", this).crmValidate();
       }
       $("form:not('[data-no-ajax-submit=true]')", this).ajaxForm($.extend({
         url: data.url.replace(/reset=1[&]?/, ''),
diff --git a/templates/CRM/Form/validate.js.tpl b/templates/CRM/Form/validate.js.tpl
new file mode 100644 (file)
index 0000000..0fde36f
--- /dev/null
@@ -0,0 +1,85 @@
+ {*
+ +--------------------------------------------------------------------+
+ | CiviCRM version 4.5                                                |
+ +--------------------------------------------------------------------+
+ | Copyright CiviCRM LLC (c) 2004-2014                                |
+ +--------------------------------------------------------------------+
+ | This file is a part of CiviCRM.                                    |
+ |                                                                    |
+ | CiviCRM is free software; you can copy, modify, and distribute it  |
+ | under the terms of the GNU Affero General Public License           |
+ | Version 3, 19 November 2007 and the CiviCRM Licensing Exception.   |
+ |                                                                    |
+ | CiviCRM 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 Affero General Public License for more details.        |
+ |                                                                    |
+ | You should have received a copy of the GNU Affero General Public   |
+ | License and the CiviCRM Licensing Exception along                  |
+ | with this program; if not, contact CiviCRM LLC                     |
+ | at info[AT]civicrm[DOT]org. If you have questions about the        |
+ | GNU Affero General Public License or the licensing of CiviCRM,     |
+ | see the CiviCRM license FAQ at http://civicrm.org/licensing        |
+ +--------------------------------------------------------------------+
+*}// http://civicrm.org/licensing
+// <script> Generated {$timeGenerated}
+(function($) {ldelim}
+  // Initialize CRM.url and CRM.formatMoney
+  CRM.url('init', '{crmURL p="civicrm/example" q="placeholder" h=0}');
+  CRM.formatMoney('init', {$moneyFormat});
+
+  // Localize select2
+  $.fn.select2.defaults.formatNoMatches = "{ts escape='js'}None found.{/ts}";
+  $.fn.select2.defaults.formatLoadMore = "{ts escape='js'}Loading...{/ts}";
+  $.fn.select2.defaults.formatSearching = "{ts escape='js'}Searching...{/ts}";
+  $.fn.select2.defaults.formatInputTooShort = function() {ldelim}
+    return $(this).data('api-entity') == 'contact' ? {$contactSearch} : {$otherSearch};
+  {rdelim};
+
+  // Localize strings for jQuery.validate
+  var messages = {ldelim}
+    required: "{ts escape='js'}This field is required.{/ts}",
+    remote: "{ts escape='js'}Please fix this field.{/ts}",
+    email: "{ts escape='js'}Please enter a valid email address.{/ts}",
+    url: "{ts escape='js'}Please enter a valid URL.{/ts}",
+    date: "{ts escape='js'}Please enter a valid date.{/ts}",
+    dateISO: "{ts escape='js'}Please enter a valid date (YYYY-MM-DD).{/ts}",
+    number: "{ts escape='js'}Please enter a valid number.{/ts}",
+    digits: "{ts escape='js'}Please enter only digits.{/ts}",
+    creditcard: "{ts escape='js'}Please enter a valid credit card number.{/ts}",
+    equalTo: "{ts escape='js'}Please enter the same value again.{/ts}",
+    accept: "{ts escape='js'}Please enter a value with a valid extension.{/ts}",
+    maxlength: $.validator.format("{ts escape='js'}Please enter no more than {ldelim}0{rdelim} characters.{/ts}"),
+    minlength: $.validator.format("{ts escape='js'}Please enter at least {ldelim}0{rdelim} characters.{/ts}"),
+    rangelength: $.validator.format("{ts escape='js'}Please enter a value between {ldelim}0{rdelim} and {ldelim}1{rdelim} characters long.{/ts}"),
+    range: $.validator.format("{ts escape='js'}Please enter a value between {ldelim}0{rdelim} and {ldelim}1{rdelim}.{/ts}"),
+    max: $.validator.format("{ts escape='js'}Please enter a value less than or equal to {ldelim}0{rdelim}.{/ts}"),
+    min: $.validator.format("{ts escape='js'}Please enter a value greater than or equal to {ldelim}0{rdelim}.{/ts}")
+  };
+  $.extend($.validator.messages, messages);
+  {literal}
+
+  var params = {
+    errorClass: 'crm-inline-error',
+    messages: {}
+  };
+
+  // use civicrm notifications when there are errors
+  params.invalidHandler = function(form, validator) {
+    if ($('#crm-notification-container').length) {
+      $.each(validator.errorList, function(k, error) {
+        $(error.element).crmError(error.message);
+      });
+    } else {
+      alert({/literal}"{ts escape='js'}Please review and correct the highlighted fields before continuing.{/ts}"{literal});
+    }
+  };
+
+  CRM.validate = {
+    _defaults: params,
+    params: {},
+    functions: []
+  };
+})(jQuery);
+{/literal}
index 502482b875a61c66779b4f930eed395e80ad0fcf..42204c30b063edc1c5225190724f5b6b3cdf2237 100644 (file)
  | see the CiviCRM license FAQ at http://civicrm.org/licensing        |
  +--------------------------------------------------------------------+
 *}
-
-{* Initialize jQuery validate *}
+{* Initialize jQuery validate on a form *}
 {* Extra params and functions may be added to the CRM.validate object before this template is loaded *}
+{if !$crm_form_validate_included and $smarty.get.snippet neq 'json' and $form and $form.formName}
+  {assign var=crm_form_validate_included value=1}
 
-{if !$crm_form_validate_included}
-{assign var=crm_form_validate_included value=1}
-
-{literal}
-<script type="text/javascript" >
-CRM.$(function($) {
-  var messages = {{/literal}
-        required: "{ts escape='js'}This field is required.{/ts}",
-        remote: "{ts escape='js'}Please fix this field.{/ts}",
-        email: "{ts escape='js'}Please enter a valid email address.{/ts}",
-        url: "{ts escape='js'}Please enter a valid URL.{/ts}",
-        date: "{ts escape='js'}Please enter a valid date.{/ts}",
-        dateISO: "{ts escape='js'}Please enter a valid date (YYYY-MM-DD).{/ts}",
-        number: "{ts escape='js'}Please enter a valid number.{/ts}",
-        digits: "{ts escape='js'}Please enter only digits.{/ts}",
-        creditcard: "{ts escape='js'}Please enter a valid credit card number.{/ts}",
-        equalTo: "{ts escape='js'}Please enter the same value again.{/ts}",
-        accept: "{ts escape='js'}Please enter a value with a valid extension.{/ts}",
-        maxlength: $.validator.format("{ts escape='js'}Please enter no more than {ldelim}0{rdelim} characters.{/ts}"),
-        minlength: $.validator.format("{ts escape='js'}Please enter at least {ldelim}0{rdelim} characters.{/ts}"),
-        rangelength: $.validator.format("{ts escape='js'}Please enter a value between {ldelim}0{rdelim} and {ldelim}1{rdelim} characters long.{/ts}"),
-        range: $.validator.format("{ts escape='js'}Please enter a value between {ldelim}0{rdelim} and {ldelim}1{rdelim}.{/ts}"),
-        max: $.validator.format("{ts escape='js'}Please enter a value less than or equal to {ldelim}0{rdelim}.{/ts}"),
-        min: $.validator.format("{ts escape='js'}Please enter a value greater than or equal to {ldelim}0{rdelim}.{/ts}")
-  {literal}};
-
-  var params = {
-    'errorClass': 'crm-inline-error',
-    messages: {}
-  };
-
-  // use civicrm notifications when there are errors
-  params.invalidHandler = function(form, validator) {
-    var errors = validator.errorList;
-    {/literal}{if !$urlIsPublic}{literal}
-      for (var i in errors) {
-        $(errors[i].element).crmError(errors[i].message);
-      }
-    {/literal}{else}
-      alert("{ts escape='js'}Please review and correct the highlighted fields before continuing.{/ts}");
-    {/if}{literal}
-  };
-
-  CRM.validate.params = CRM.validate.params || {};
-  $.extend(CRM.validate.params, params);
-  $.extend($.validator.messages, messages);
-
+  {literal}
+  <script type="text/javascript">
+    CRM.$(function($) {
+      $("#{$form.formName}").crmValidate();
+    });
+  </script>
   {/literal}
-  {if $form && $form.formName}
-    $("#{$form.formName}").validate(params);
-    {literal}
-    // Call any post-initialization callbacks
-    if (CRM.validate && CRM.validate.functions.length) {
-      $.each(CRM.validate.functions, function(i, func) {
-        func();
-      });
-    }
-    {/literal}
-  {/if}
-});
-</script>
 {/if}