Making non-core language packs

From Joomla! Documentation

This page has been archived. This page contains information for an unsupported Joomla! version or is no longer relevant. It exists only as a historical reference, it will not be improved and its content may be incomplete and/or contain broken links.

To make a non-core language pack in 2.5 is quite different from making a Core pack.

The type of package is a "file" type.

Here is a typical xml including installing ini files into the administrator and site CORE default language folders for one language and one extension only. Many languages and many extensions can be included in the same .zip.

<?xml version="1.0" encoding="utf-8"?>
<extension type="file" version="2.5" method="upgrade">

	<!-- Please use a unique name to make uninstall to work. Should be identical to your manifest filename. -->
	<author>French Translation Team</author>
	<creationDate>24 Janvier 2012</creationDate>
	<copyright>(C) 2005-2012 Whoever</copyright>
	<license> GNU/GPL</license>
	<description>This fr-FR lang pack for myextension has been installed successfully</description>

	<!-- Fileset definition -->

		<!-- back-end -->
		<files folder="admin/fr-FR" target="administrator/language/fr-FR">

		<!-- front-end -->
		<files folder="site/fr-FR" target="language/fr-FR">

The .zip in this case is composed of the xml above and 2 folders: site and admin, each of them containing a fr-FR folder with the ini files.


site/fr-FR/ + all ini files + index.html

admin/fr-FR/ + all ini files + index.html

The result is the installation of the ini files in an existing fr-FR folder or creating one if does not exist.

It has no impact on existing files. Uninstalling the "File" pack (Extensions Manager=>Manage=>Filter by "file") will only uninstall the ini files listed.

NOTE: In 2.5, except if one uses a specific script, the language xx-XX folders will always be created if they do not already exist.

Make it multi-language[edit]

If you want to pack all the available languages into one installable file, but want to be able to use separate file extensions (as explained above) to be able to uninstall or install them separately, a package with a small script is needed.

Following code will only install those languages which exist in your Joomla installation. If new languages are added, package needs to be installed again.

pkg_kunena_languages.xml (in our example):

<?xml version="1.0" encoding="utf-8"?>
<extension type="package" version="2.5" method="upgrade">

	<!-- Put anything into here, name is only shown in extension manager. -->
	<name>Kunena Language Pack</name>

	<!-- Filename without "pkg_" prefix. Must be unique or uninstall breaks. -->

	<author>Kunena Team</author>
	<copyright>(C) 2008 - 2012 Kunena Team. All rights reserved.</copyright>
	<description>Language pack for Kunena forum component.</description>

	<files folder="language">
		<!-- Content will be added by our installer script -->


defined( '_JEXEC' ) or die();

// Needed in Joomla < 2.5:
jimport( 'joomla.filesystem.folder' );
jimport( 'joomla.installer.installer' );

// FIXME: remember to change class name
class pkg_kunena_languagesInstallerScript {

	// FIXME: remember to change language package name
	protected $name = 'com_kunena';

	public function uninstall($parent) {
		// Remove languages.
		$languages = JFactory::getLanguage()->getKnownLanguages();
		foreach ($languages as $language) {
			echo $this->uninstallLanguage($language['tag'], $language['name']);

	public function preflight($type, $parent) {
		if (!in_array($type, array('install', 'update'))) return true;

		$app = JFactory::getApplication();

		// If you want, you can detect your extension in here and fail with a message if it is not installed.

		// Get list of languages to be installed. Only installs languages that are found in your system.
		$source = $parent->getParent()->getPath('source').'/language';
		$languages = JFactory::getLanguage()->getKnownLanguages();

		$files = $parent->manifest->files;
		foreach ($languages as $language) {
			$search = JFolder::files($source, $language['tag']);
			if (empty($search)) continue;

			// Generate something like <file type="file" client="site" id="com_kunena_fi-FI"></file>
			$file = $files->addChild('file', array_pop($search));
			$file->addAttribute('type', 'file');
			$file->addAttribute('client', 'site');
			$file->addAttribute('id', $this->name.'_'.$language['tag']);
			echo sprintf('Installing language %s - %s ...', $language['tag'], $language['name']) . '<br />';

		if (empty($files)) {
			// No packages to install: replace failure message with something that's more descriptive.
			$app->enqueueMessage(sprintf ( 'Your site is English only. There\'s no need to install language pack.' ), 'notice');
			return false;

		return true;

	public function uninstallLanguage($tag, $name) {
		$table = JTable::getInstance('extension');
		$id = $table->find(array('type'=>'file', 'element'=>"{$this->name}_{$tag}"));
		if (!$id) return;

		$installer = new JInstaller();
		$installer->uninstall ( 'file', $id );

Then just copy all the language zip files (or installable directories) under language folder. Just make sure that they all use the same naming convention before creating the installation pack.

The nicest thing in above installer pack is that there's no need to change anything if languages for your extension get added, removed or updated.