Creating a Site Module for Joomla 3.x - Part 3

Where are we going?

television icon 64x64pdf icon 64x64zip icon 64x64Now that we have written a minimalist module for Joomla, let’s move on to do something a little more useful than printing “Welcome to my module!” to the screen. If you are asking why did I start with that, well the answer is, in short, it provides us a template in which we can copy over and use as the basis of a new module, a tool of sorts. Anything that saves a little time is a good thing, right.

Now, to get back on track. The module we are going to write is a random quote module and over the course of writing it we will cover database access, views or layouts, helper files, module parameters, and other tidbits along the way. Of course, this will happen over a few tutorials, but by the end of it, you should have a good grasp on how to write about any type of module you like.

Lay the foundation

Remember our basic minimalist module? Well create a new folder where were ever you keep your Joomla projects called mod_random_quote, and copy your three minimalist files to this folder. To recap, that should be index.html, mod_smallest.php and mod_smallest.xml, (or whatever you called your module if you deviated from the tutorials) Rename the PHP and XML files to mod_random_quote.php and mod_random_quote.xml respectively. Next, open the mod_random_quote.xml file and make the following changes marked in red.

<?xml version="1.0" encoding="utf-8"?>
<extension type="module" version="3.5" client="site" method="upgrade">

<name>Random Quote</name>
<author>Joe Hildreth</author>
<creationDate>05 JUL 2016</creationDate>
<copyright>(c)2016 Joe Hildreth, All rights Reserved</copyright>
<license>GNU General Public License V2 or later</license>
<authorEmail>This email address is being protected from spambots. You need JavaScript enabled to view it.<;/authorEmail>
<authorUrl>http://www.myheap.com</authorUrl>
<version>1.0.0</version>

<description>Displays a Random Quote</description>

<files>
<filename module="mod_random_quote">mod_random_quote.php</filename>
<filename>mod_random_quote.xml</filename>
<filename>index.html</filename>
</files>

</extension>

In the above code we changed some of the data to represent our new module. Now, you have to admit that we saved a little time the with cut and paste and a few edits. Don’t forget, you can change the meta-data between the <name> and <description> tag to anything you like. With your edits made, save the file and create an archive. Install it into Joomla. Set a position and test it to make sure all is good. If not, look for errors in your manifest file, as this will usually be the cause of a problem at this stage. When all is well and good let’s take the next step.

Adding a Language File

One of the cool features about Joomla is it’s ability to cater to many different languages through the use of language files, and there is no reason our module should be any different. Even if you don’t speak another language, by breaking out certain parts of your module to use language strings you allow someone else to translate your module into another language, and it is simple to do.

Before discussing the actual language files, let’s first talk about where they are stored in the file system. If you look in the root of the site application file system you will see a folder called language and upon examining the contents of this folder you will see that a folder exists for each language installed. The naming convention for these folders consist of two lowercase letters followed by a dash and then two uppercase letters. These letters have the following meaning. The first two letters are the international standardized code for a language. For example, en = English, de = German, nl = Dutch, etc. The second two letters represent a dialect if one exists, for example en-GB means English of the Great Brittan dialect, en-US means English of the United States dialect. You get the idea.

My installed copy of Joomla, was installed with the en-GB language files, so if you open the en-GB folder you will see quite a few files located there. All of these files follow a naming convention that looks something like en-GB.<name-of-extention>.ini and en-GB.<name-of-extension>.sys.ini. These two files, the .ini and the .sys.ini are used in different areas of Joomla. The .ini files hold the translation strings for your extension that the end user will see. The .sys.ini file holds the translation strings that are used by Joomla itself. To clarify, the .sys.ini file will hold translations for the following:

  1. During the extension's installation, to allow localizing the post-installation messages,
  2. to build the administrator Components menu,
  3. to localize component parameters and menu parameters
  4. and in the Extension Manager→Manage screen.

And the .ini file will hold everything else. Don’t worry too much on it, I will clarify as we go along. We will also see the same thing in the administrator application on the back end. See administrator/language from your root web folder.

Along with these locations, you can also store your language files inside your extension's folder as well. For example we would have mod_random_quote/language/en-GB/en-GB.mod_random_quote.ini and .sys.ini files.

Joomla can read these language files from either location, so the real question becomes, which do I choose? There is some debate but the general consensus is to keep your language files with your extension and leave the global language files for the Joomla CMS. That is the method we will use in this tutorial. If you would like to know more about Joomla’s Language files, please see https://docs.joomla.org/Specification_of_language_files.

Now, go to your module’s project folder and create the following folders and files until your directory tree looks like the following:

mod_random_quote/
mod_random_quote/index.html
mod_random_quote/mod_random_quote.php
mod_random_quote/mod_random_quote.xml
mod_random_quote/language/
mod_random_quote/language/index.html
mod_random_quote/language/en-GB/
mod_random_quote/language/en-GB/index.html
mod_random_quote/language/en-GB/en-GB.mod_random_quote.ini
mod_random_quote/language/en-GB/en-GB.mod_random_quote.sys.ini

Take notice that we have added an index.html file to every folder to prevent the web server from listing the contents of a folder when there is no default file available. I just copied and pasted mine from the mod_random_quote folder.

When I discussed the manifest file in previous tutorials, I mentioned that the <name> and <description> tags were translatable. Joomla will use a translation string, if one is available to display this text, if not, it will use the text that is between the opening and closing tags. These strings are used by Joomla when you are managing the extension, so this gives us a hint to which language file the string belongs in. Open your manifest file and make the following changes:

<?xml version="1.0" encoding="utf-8"?>
<extension type="module" version="3.5" client="site" method="upgrade">

<name>MOD_RANDOM_QUOTE</name>
<author>Joe Hildreth</author>
<creationDate>05 JUL 2016</creationDate>
<copyright>(c)2016 Joe Hildreth, All rights Reserved</copyright>
<license>GNU General Public License V2 or later</license>
<authorEmail>This email address is being protected from spambots. You need JavaScript enabled to view it.<;/authorEmail>
<authorUrl>http://www.myheap.com</authorUrl>
<version>1.0.0</version>

<description>MOD_RANDOM_QUOTE_DESCRIPTION</description>

<files>
<filename module="mod_random_quote">mod_random_quote.php</filename>
<filename>mod_random_quote.xml</filename>
<filename>index.html</filename>
</files>

</extension>

In the above file we have changed the name and description strings to MOD_RANDOM_QUOTE and MOD_RANDOM_QUOTE_DESCRIPTION. There are a couple of things to take note of here. Standard practice is to start your translation strings with the name of your extension to prevent name-space collisions with other extensions. In this example MOD_RANDOM_QUOTE and to append to them text that describes what the string is for. For example MOD_RANDOM_QUOTE_DESCRIPTION. The other thing to take note is that language strings are always written in upper case letters and words are separated with the underscore character. You may not use spaces in your language strings. There are a few other restrictions and I encourage you to read the docs on language files located at https://docs.joomla.org/Specification_of_language_files.

After you install your module, Joomla will look for these two strings in the .sys.ini language file for the users selected language and if they exist will replace the language strings with the string from the language file. If it cannot find the string, it will use the COM_RANDOM_QUOTE… string in the manifest file. So now, lets add our strings to the .sys.ini file. Open the following file:

mod_random_quote/language/en-GB/en-GB.mod_random_quote.sys.ini

and add the following to it.

; Translation strings for the Joomla system to use
MOD_RANDOM_QUOTE="Random Quote"
MOD_RANDOM_QUOTE_DESCRIPTION="Displays a Random Quote."

You can use comments in your language files but they must start with a semi-colon and are single line comments. So the first line is a comment to remind us that this language file exists to hold language strings for the Joomla System or CMS. The next two lines contain the strings we used in the manifest file and they are set to whatever English string we wanted to be displayed.

If you wanted to support another language with your component, it is as simple as creating a folder under the language folder following the naming convention and create these same two files. For example, say I want to support German, I would create the following files:

mod_random_quote/language/de-DE/
mod_random_quote/language/de-DE/index.html
mod_random_quote/language/de-DE/de-DE.mod_random_quote.ini
mod_random_quote/language/de-DE/de-DE.mod_random_quote.sys.ini

And the de-DE.mod_random_quote.sys.ini file would contain the following

; Translation strings for the Joomla system to use
MOD_RANDOM_QUOTE="Zufalls-Zitat"
MOD_RANDOM_QUOTE_DESCRIPTION="Zeigen Sie ein zufälliges Zitat."

Above, the language strings contain the German strings that we want to use in our module. (NOTE: I do not speak German, and the strings above were created with Google Translate.)

Now that we have finished adding our language strings we need to tell Joomla to install them with the rest of our module. To do that, open your manifest file and add the line in red.

<?xml version="1.0" encoding="utf-8"?>
<extension type="module" version="3.5" client="site" method="upgrade">

<name>MOD_RANDOM_QUOTE</name>
<author>Joe Hildreth</author>
<creationDate>05 JUL 2016</creationDate>
<copyright>(c)2016 Joe Hildreth, All rights Reserved</copyright>
<license>GNU General Public License V2 or later</license>
<authorEmail>This email address is being protected from spambots. You need JavaScript enabled to view it.<;/authorEmail>
<authorUrl>http://www.myheap.com</authorUrl>
<version>1.0.0</version>
<description>MOD_RANDOM_QUOTE_DESCRIPTION</description>

<files>
<folder>language</folder>
<filename module="mod_random_quote">mod_random_quote.php</filename>
<filename>mod_random_quote.xml</filename>
<filename>index.html</filename>
</files>

</extension>

 

Recall that the files section of the manifest tells Joomla the files that need to be copied to the front end of our extension. Up to this point we used the tag <filename> to tell Joomla the individual file that we want to copy. If we had to do a single file at a time this section would grow quite fast, but fortunately, Joomla allows us to specify folders too. The <folder> tag names a folder that you wish to copy over. Joomla will create the folder and copy all of its contents to the module’s folder on the site application. It will make the copy recursive meaning that it will get any sub folders and their contents as well.

That is all there is to adding Multi-Language support to your Joomla extension. Simply create a folder to hold the language files in and create the .ini and .sys.ini files for the translations. Joomla will load the correct strings based on the selected language of the user and the default language that Joomla was installed with. Using language strings in your module itself is pretty simple too. You use a method called JText::_() with the language string as a parameter and Joomla will insert the proper language text for you. We will cover that more later.

Checking our work

We have made the necessary changes to our module to support internationalization. Let’s check our work before we move on. Go to your projects folder and create an archive of your module being sure to include the language folder that we added. Go to the back end and install the updated module. If you get any errors installing, be sure to check your manifest file for errors.

With the module installed, navigate to the manage screen, you should see your module listed as before and when you mouse over the module name you should see the description. If instead you see the language string you provided in the Manifest file for either the name or the description, you may want to check the following:

  1. Make sure the string you used in the manifest file matches the string you used in the language file.
  2. Make sure that you have the language strings in the correct language file. They should be in en-GB.mod_random_quote.sys.ini file.
  3. Make sure you have given the correct name to the .sys.ini file itself. If misnamed, Joomla cannot find the file.

A view from a different angle

Joomla supports what is called layouts. Layouts allow you to display the information you want in different views. Say, for example, you sell books and every week you have a sale and you use a module to display the list of books on sale. Now maybe on the homepage you want them displayed as a simple list, but on other pages you would like them to display as a list with a note of the sale price. Well, the good news is that you do not have to write separate modules to do these separate tasks. You can make your module display itself differently based on some parameters. We will get into just this scenario later, but for now, you need to know that Joomla can do it. Now, if our module is called with no specific view (or layout) then Joomla looks for one called default. Like everything else with Joomla, there is a file layout that we have to follow for it to work correctly. Additionally, there is some code that we need to add so that Joomla knows which view or layout we want. To get started, add the following folder and files to your project marked in red.

mod_random_quote/
mod_random_quote/index.html
mod_random_quote/mod_random_quote.php
mod_random_quote/mod_random_quote.xml
mod_random_quote/language/
mod_random_quote/language/index.html
mod_random_quote/language/en-GB/
mod_random_quote/language/en-GB/index.html
mod_random_quote/language/en-GB/en-GB.mod_random_quote.ini
mod_random_quote/language/en-GB/en-GB.mod_random_quote.sys.ini
mod_random_quote/tmpl/
mod_random_quote/tmpl/default.php
mod_random_quote/tmpl/index.html

Create a folder named tmpl (In my mind this folder is shorthand for template.) in your project file and copy your empty html file to it. Then make an empty file called default.php. Now open the default.php file and add the following code.

<?php
defined(‘_JEXEC’) or die;

echo ‘Random Quote Module’;

Save the file and close it. The code above first checks that it is being executed inside Joomla by checking if the _JEXEC constant has been defined, and if it has prints the string “Random Quote Module”. So we have our default view or layout written and Joomla knows to look for this file when a specific layout has not been given to it. Now we need to edit the module’s entry PHP script and let Joomla know we are using layouts. Open the mod_random_quote.php file and remove the echo statement and add the lines in red.

<?php
defined('_JEXEC') or die;

require JModuleHelper::getLayoutPath('mod_random_quote', 'default');

Joomla has an abstract class called JModuleHelper that has methods to work with modules. Most of these are used by Joomla when it is parsing and running modules, but one of them is geared to getting a specific layout for a module, getLayoutPath() and what it does is pretty straight forward, you supply it two parameters. The first is what module are you looking for and in our case it is our module, mod_random_quote. The second parameter is the layout you want, and in our case we want the default layout (the default.php file) for this module. What is returned is the path and filename of the layout (or view) we are looking for. This file is then brought in place with the PHP require statement.

In this case we are asking for the default view explicitly, but as we expand the capability of the module later, we will introduce module parameters which we will use to allow the administrator to choose from different layouts.

Finally we need to let Joomla know to copy our new files when we install the module. Open the manifest file and add the following line:

<?xml version="1.0" encoding="utf-8"?>
<extension type="module" version="3.5" client="site" method="upgrade">

<name>MOD_RANDOM_QUOTE</name>
<author>Joe Hildreth</author>
<creationDate>05 JUL 2016</creationDate>
<copyright>(c)2016 Joe Hildreth, All rights Reserved</copyright>
<license>GNU General Public License V2 or later</license>
<authorEmail>This email address is being protected from spambots. You need JavaScript enabled to view it.<;/authorEmail>
<authorUrl>http://www.myheap.com</authorUrl>
<version>1.0.0</version>
<description>MOD_RANDOM_QUOTE_DESCRIPTION</description>

<files>
<folder>language</folder>
<folder>tmpl</folder>
<filename module="mod_random_quote">mod_random_quote.php</filename>
<filename>mod_random_quote.xml</filename>
<filename>index.html</filename>
</files>

</extension>

In the above code we have added another <folder> tag to let Joomla know to copy this folder and all of its contents to the module’s folder on the front end or site application of the website. Once you have added the line save and close the file.

Checking our work … again

In your project folder, delete your old archive and create a new one, being sure to include both the language and tmpl folders with the files. Go to the back end and install your module again. If you receive any error notifications when installing, double check your manifest file for errors. When you have the module installed go to the front end and see that it works. It should display the text “Random Quote Module”, which we know is coming from the default layout.

If you have any errors on the front end, check that you included the tmpl folder in your manifest and that the spelling is correct. Check the spelling of your default.php file in the tmpl directory, and finally check your call to the getLayoutPath() method that you don’t have a typo in the method name or one of it’s parameters.

Some Final Thoughts

I have talked about internationalizing the module by using language strings and the concept of different layouts or views when displaying the contents of the module. We will see both these topics come up again later as we develop this module.

In the next tutorial, we will develop the database for our module using a few tools to help us generate the SQL file that Joomla will need to install the data. I will also cover the SQL files required for installing, updating and removing a module from Joomla. I will also introduce versioning the module as it plays an important role once you start with a database.

If you have any questions, please feel free to post on my YouTube channel located at https://www.youtube.com/c/MyHeap or use the contact link on my website by going to http://www.myheap.com

END OF TUTORIAL