In the last article, we looked at creating MODX settings, but only in a single language. If your custom setting fields need to appear in more than one language in the MODX Manager, this article will show you how it's done. The term for this is internationalization. It's also known as i18n. For a long time, I assumed that the 18 in i18n was related to a version of some internationalization agreement. It's not, though. It came from people getting tired of typing the word "internationalization." The 18 represents the 18 letters between the "i" and the "n" of internationalization.
The material in this article refers to all Settings in MODX (System Settings, Context Settings, User Settings, and UserGroup settings).
Internationalizing Settings is Different
If you've used MODX Lexicon strings before in language tags, or in PHP or JavaScript code, you're used to coming up with
your own key for each string you want to internationalize. If you want to display a setting that sets the maximum value
for something, your key might be max_volume. In the English (en) lexicon file you would have:
$_lang['max_volume'] = 'Maximum Volume';
In other lexicon files, the key would be the same but the value would be translated to another language. So you come up with both the key and the value for each lexicon string.
For the name, description, and area of settings, things are different. You create the key of the Setting, but not
the keys used for those three lexicon strings. They are created automatically by MODX based on the Setting's key.
Internationalizing the settings is a little tricky the first time you do it. It involves using several similar language keys that are easily confused.
Here's a tip to get you started: If at all possible, do not use the word "setting" in the key of your setting. Doing that will make dealing with internationalization even more confusing than it already is.
The Keys
The lexicon keys for the three "internationalizationable" fields are generated behind the scenes by MODX. You won't see them in the Manager, but you'll need to know them to use more than on language for those fields.
I just looked up "internationalizationable" on Google, which tells me it doesn't exist, though its intent is clear. I wonder if I'll get the credit if it enters the OED (Oxford English Dictionary) at some point. Google's AI suggests calling them fields "designed with internationalization in mind," which is way longer than the non-word I just coined.
When you fill out the setting-creation form, MODX creates the keys, then takes your values for them and enters the
key-and-value pairs into the modx_lexicon_entriestable in the database. It does this for all settings that you create
in the Manager. It only does this for the current language used in the Manager. Because the table has a field for the
language, you could internationalize things by changing the manager language over and over, and re-creating all your
settings. I don't think anyone actually does this, since it's much easier to create a new lexicon file for each
language. To do that, you have to know what keys MODX creates.
To create the lexicon key for the name field, MODX takes key of the Setting and adds setting_ as a prefix. For the
description fields, MODX takes the key of the Setting, adds setting_ as a prefix, and _desc as a suffix. For the
area field, MODX adds area_ as a prefix. The setting key itself is never translated because it has to be the same for
any language. Here's a short cheatsheet:
Name Field: 'setting_' + key
Description Field: 'setting_' + key + '_desc'
Area Field: 'area_' + whatever_you_enter_in_the_form;
These are ironclad rules, and one reason why you can't change the key of an existing Setting. If you did, your lexicon strings would stop working. If you want to change the key of a Setting, you need to delete the setting and create a new one. You also have to update any lexicon files for the Setting.
Here's an example using the MODX site_start System Setting:
<b>Key</b>: `site_start`
<b>Name</b>: `setting_site_start`
<b>Description</b>: `setting_site_start_desc`
<b>Area</b>: `site`
Here are the lexicon strings for the name, description, and area fields in MODX's English lexicon file for the
site_start setting (core\lexicon\en\setting.inc.php):
$_lang['setting_site_start'] = 'Site start';
$_lang['setting_site_start_desc'] = 'Enter the ID of the Resource you want to use as homepage here.
<strong>NOTE: make sure this ID you enter belongs to an existing Resource, and that it has been published!</strong>',
$_lang['area_site'] = 'Site';
You might expect to see the first two keys above in the database in the
modx_system_settings table, but they're not there. They do appear in the
modx_lexicon_entries table, but only in the language used in the Manager when the settings were
created. MODX loads those from the database when you load any Manager page. For any other language, MODX loads the
lexicon entries from the appropriate lexicon file if it can find it (more on this in a bit).
The lexicon keys for the name, description, and area fields are created
on-the-fly by MODX. They're based on the Setting's key when MODX needs to find the lexicon string for each one. The
area key is not handled the same way as the other two — more on that in a bit.
Some Tips
It's not required, but by convention, lexicon keys and Setting keys are all lowercase. It will make your life much easier if you always follow this convention. If you don't, you'll find yourself constantly looking in your lexicon files for the correct capitalization of your keys (i.e., did I use fileName, filename, or FileName?).
This is just a suggestion, but if you always separate the words in your keys with an underscore character (_), you
won't have to try to remember where you used a dot, camel case, or an underscore. This will also put them in the same
format as all the MODX core lexicon keys.
It's recommended that you prefix your own lexicon keys, for extras you create, with a lower case prefix named for your extra. This keeps your lexicon strings from colliding with MODX's build-in lexicon strings. Some developers use a dot to separate the prefix from the rest of the key. If you always do this, it will work, but whatever you do, try to be consistent. It will save you valuable time. I used to use a dot for prefixes, but now I try to use an underscore for everything related to the lexicon.
The Namespace
When creating a setting, you need to fill in the namespace field if you want to use more than one language with your setting(s). You could use an existing namespace on the site (e.g., core), but doing that would mean having your settings mixed up with the others and potentially having your lexicon file buried among many other lexicon files. If you create your own namespace, it will be much easier to find both your settings and your lexicon file.
The only time I use the core namespace for a setting in an extra I've created is when I don't want the setting to be
part of the transport package. I use MyComponent to create my extras, and it will only package Settings that are
in the package's namespace. For example, I often create settings for the extra's core_path and assets_path that
refer to my development environment, so when I run the extra locally, it will use the code from the development
environment where I will be working on the extra's code. I don't want these paths to be part of the package, so I put
them in the core namespace.
Creating an Internationalized Custom System Setting
Let's walk through creating a custom System Setting with a specific example using a custom namespace called "mysettings."
First, you'd create the namespace by going to System (gear icon) -> Namespaces -> Create New button. Enter the name
(mysettings) and the following Core Path: {core_path}components/mysettings/. Don't put a slash after {core_path},
and don't forget the trailing slash at the very end. Save the namespace. The Core Path is necessary so that MODX can
find the lexicon file when displaying any settings you create.
If you have images, CSS files, or JavaScript files for a project, they will need to be available in a visitor's browser.
That means you can't put them in or under the core directory. The place for them is under the assets directory.
Putting them in assets/components/namespace_name/ makes them easy to find.
So it makes sense to also specify an assets_path for your namespace with this value:
{assets_path}components/extra_namepace_name_here/
Notice that we put our namespace directories under the components directory rather than directly under the core or assets directory. This is not required, but I think it's a good location for your own stuff because it keeps it separate from the MODX core files and MODX will never alter files in that location. It's where MODX extras go, and if you look, you'll probably see a few of them there. For an extra, the namespace name is usually a lowercase version of the extra's name.
Once you've created the core_path setting for your namespace, you can specify the mysettings namespace in any custom
settings you create, so you can find them easily in any settings tree.
In order to show how the lexicon files work, we need to create a setting in our new namespace. Let's make it a System
Setting (be sure you've successfully created the mysettings namespace first). We'll use custom_theme for the key,
and we'll use it as an example in a later article. Go to System -> System Settings. Be sure you're on the "System
Settings" tab and click on the "Create New Setting" button. Use the following values for the setting's fields:
Key: custom_theme
Name: Custom Theme
Description: Custom CSS path
Field Type: Textfield
Namespace: mysettings
Area Lexicon entry: custom
Value: Some Value
(Later, we'll change the last one, some Value to the actual path of a CSS file.)
When you save the System Setting, MODX will put the values you entered for the Name and Description into the
modx_lexicon_entries table using setting_custom_theme and setting_custom_theme_desc as the keys, and the values
you entered as their values. It puts exactly what you entered in the Area field into the area field of the
modx_system_setting table record for the System Setting, along with the key, the namespace, and the language code
(e.g., en). We'll see how that's used below.
Save the setting and check to make sure it's in the grid. You can search for it several ways. To search for a single
setting, you can put the key, or part of the key, in the search box at the upper right of the grid and press enter. To
see all your custom settings, you can use the "Namespace" dropdown at the top of the settings grid (it will always show
core, which is the default namespace). Scroll down and select "mysettings" in the namespace drop-down list. MODX
should show your namespace just below the input box. The grid should then show just the settings in your namespace. If
you've entered an area for a setting or group of settings, you can select the area in the dropdown input just to the
right of the namespace one to see just the settings in that area.
The Language (Lexicon) File
We said the actual lexicon strings are in the lexicon file, but where does it go and what's in it?
First, the name and location. The English lexicon files for MODX built-in System Settings are in the file
core/lexicon/en/setting.inc.php — (notice that in the file name it's "setting" not "settings"). The equivalent
file for your custom System Setting's lexicon entries would be core/components/mysettings/lexicon/en/setting.inc.php.
That is where MODX will look for them first. It's not the only possible location, though. MODX will also find them if
they are in a file in the same directory called default.inc.php. The authors of some MODX extras choose to put all
their lexicon strings in that default file, especially when they don't use a lot of lexicon strings.
Since we're only dealing with settings, let's put ours in this spot:
core/components/mysettings/lexicon/en/setting.inc.php
To create the lexicon file, go to the Files tab in the MODX Manager. The components directory should already exist
under the core directory if you've installed any extras. If not, create it by right-clicking on the core directory
and selecting "Create Directory Here." Put components in the name field (you can leave the paths blank) and save the
directory.
Right-click on the core/components directory and select Create Directory Here. Put mysettings/lexicon/en in the Name
field and click on the save button.
When you're finished adding the directories, you should see this structure in the tree:
core
components
mysettings
lexicon
en
Now, right-click on the en directory and select "Create File." call the file setting.inc.php and add this to its
content:
<?php
/**
* mysettings Setting English lexicon topic
*
* @language en
* @package modx
* @subpackage lexicon
*/
/* Name */
$_lang['setting_custom_theme'] = 'Custom CSS Path';
/* Description */
$_lang['setting_custom_theme_desc'] = 'Path to custom CSS file';
/* Area */
$_lang['area_custom'] = 'My Custom Settings';
Save the file
We've added comments showing the Name, Description, and Setting fields. Normally, these wouldn't be there, nor would the empty lines between the lexicon entries. The comment at the top is common and will often include the name of the author and/or a copyright notice. It's optional, though. The only required part of the file is PHP tag at the top, and the lexicon entry lines that start with $_lang
Important: Do not put a closing PHP tag at the end of the file.
All lexicon entries in MODX take this form:
$_lang['key'] = 'Value to replace the key';
Notice that the Name and Area keys are exactly what you entered when you created the setting. The Area key, though, is a little different. We just put custom in the Area field when creating the setting. In the lexicon file, though, it gets the area_ prefix because when MODX goes to fill in the area in the Manager, that's what it looks for — area_ plus that actual entry in the form.
I should mention that you don't need to fill in the area field when creating a setting. MODX doesn't use it for anything but displaying your settings. If you'll have a small number of settings, you don't really need to specify areas for them. If you have a lot of settings, though, when MODX shows the settings in your namespace, it will automatically arrange them in groups by area, with the area name as a heading above each section.
Obviously, if you haven't entered any areas, you don't need to create lexicon strings for them in your lexicon files.
Assuming that your Manager language is English, if you've been following closely, you may have realized that the first two entries (for the name and description) in the lexicon file not actually necessary, (though the area one is). That's because MODX entered those in the modx_lexicon_entries table. In fact what you enter for them will be ignored, since MODX will quit looking when it finds them there in the database. The area one is necessary because without it, you'll just see what you entered in the form. If that area line is in the lexicon file, MODX will use its value in place of what's in the form. When it sees what's in the form MODX (in this case "custom," MODX sees "custom in the area field of the modx_system_settings table, and will look for area_custom in the lexicon file and use its value in the grid.
Even though they're not strictly necessary, it's still important to have all three entries in the lexicon file, because we'll copy that file to create the entries for other languages.
Coming Up
In this article, we've seen how internationalize MODX settings. In the next one, we'll look at how to create lexicon files for other languages.
Bob Ray is the author of the MODX: The Official Guide and dozens of MODX Extras including QuickEmail, NewsPublisher, SiteCheck, GoRevo, Personalize, EZfaq, MyComponent and many more. His website is Bob’s Guides. It not only includes a plethora of MODX tutorials but there are some really great bread recipes there, as well.