Language Files - Developer Information on Array based Language files

Structure of Language Packs for Zen Cart 1.5.8 and above

In Zen Cart 1.5.8, the language file structure was modified so that the PHP define statement is no longer used directly to set a language constant. The reason for this is that newer versions of PHP will emit warning messages when a constant is redefined (in an override vs core file), so the old approach would create debug logs if something wasn’t done.

The new design builds an array of language definitions which are built into constants once all of them are read. For this reason, the new files are called array based language files (as opposed to the older define based language files).

So for example, in Zen Cart 1.5.7, the file includes/languages/english/login.php would have:

define('HEADING_TITLE', 'Welcome, Please Sign In');

In Zen Cart 1.5.8, the file includes/languages/english/lang.login.php would have:

$define = [
...
    'HEADING_TITLE' => 'Welcome, Please Sign In',
... ]; 

with a define to be done later after all the strings had been gathered.

Using arrays allows for the following kinds of behavior:

  • Create a set of language definitions in the storefront override files, but run the base file to ensure that any missing definitions are created, while not updating any definitions that are changed in the override.

  • Create a definition in the main language file which works for most cases, but allow it to be overridden in a per-page language file.

In the process of doing this work, the language files were reviewed for duplicates, and consolidation was done where appropriate to reduce the burden on translators.

Loading a language file

If you need to specifically include a language file, the old style of doing so

  $langfile = DIR_WS_LANGUAGES . $_SESSION['language'] . "/modules/order_total/" .  "ot_group_pricing.php";
  include_once ($langfile);

will no longer work for 1.5.8 and above. However, plugin authors may want to make their code compatible with both 1.5.7 and 1.5.8. Here’s one approach, which also allows for template overrides:

  $filename = "ot_group_pricing.php"; 
  $folder = "/modules/order_total/";  // end with slash 
  $old_langfile = DIR_WS_LANGUAGES . $_SESSION['language'] . $folder .  $filename; 
  $new_langfile = DIR_WS_LANGUAGES . $_SESSION['language'] . $folder .  "lang." . $filename; 
  if (file_exists($new_langfile)) {
     global $languageLoader; 
     $languageLoader->loadExtraLanguageFiles(DIR_FS_CATALOG . DIR_WS_LANGUAGES,  $_SESSION['language'], $filename, $folder); 
  } else if (file_exists($old_langfile)) {
     $tpl_old_langfile = DIR_WS_LANGUAGES . $_SESSION['language'] . $folder .  $template_dir . '/' . $filename; 
     if (file_exists($tpl_old_langfile)) {
        $old_langfile = $tpl_old_langfile; 
     }
     include_once ($old_langfile);
  }

If the file to be loaded was just in includes/languages/english/ (and not the modules/order_total subfolder), the changes to the code above would just be for the first two variables. To load the file includes/languages/english/lang.media_common.php it would be,

  $filename = "media_common.php"; 
  $folder = "/";  // end with slash 

On the admin side, you can do something like this. Assume the file to be loaded is admin/includes/languages/english/some-custom-file.php in 1.5.7 and admin/includes/languages/english/lang.some-custom-file.php in 1.5.8:

if (function_exists('zen_get_zcversion') && zen_get_zcversion() >= '1.5.8') { 
   $filename = 'some-custom-file.php';
   $languageLoader->loadExtraLanguageFiles( DIR_WS_LANGUAGES, $_SESSION['language'],  $filename, '/');
} else {
   require 'includes/languages/english/some-custom-file.php'; 
}

Handling back references within a file

In Zen Cart 1.5.7 and below, structures like the following were possible:

  define('TEXT_GV_NAME','Gift Certificate');
...
  define('BOX_INFORMATION_GV', TEXT_GV_NAME . ' FAQ');

In 1.5.8, you must create array elements which reference earlier array entries after creating the entire $define array.

$define = [
...
    'TEXT_GV_NAME' => 'Gift Certificate',
...
]; 
$define['BOX_INFORMATION_GV'] = $define['TEXT_GV_NAME'] . ' FAQ';

This example is taken from includes/langauges/lang.english.php.

Handling back references between files

Prior to Zen Cart 1.5.8, the define operations were done incrementally, so a language file which was loaded later could refer to one loaded earlier.

For example, a file in includes/languages/english/extra_definitions/ could do this:

define('ABOUT', '<li><a href="' . zen_href_link(FILENAME_ABOUT_US) . '">' . BOX_INFORMATION_ABOUT_US . '</a></li>');

This is no longer permitted; the constant must be replaced by a string.

define('ABOUT', '<li><a href="' . zen_href_link(FILENAME_ABOUT_US) . '">' . 'About Us' . '</a></li>');

Language File Help:




Still have questions? Use the Search box in the upper right, or try the full list of FAQs. If you can't find it there, head over to the Zen Cart support forum and ask there in the appropriate subforum. In your post, please include your Zen Cart and PHP versions, and a link to your site.

Is there an error or omission on this page? Please post to General Questions on the support forum. Or, if you'd like to open a pull request, just review the guidelines and get started. You can even PR right here.
Last modified November 26, 2022 by Scott C Wilson (fe5d08f8).