# Coppermine Photo Gallery v1.5.x: Documentation and Manual

# Translation Guide

## Translators wanted!

One of the major features of a Coppermine photo gallery is the fact that all page content can be displayed in different languages, with translations being contained in one file (located inside of the coppermine lang directory ). If you use Coppermine and feel that you would like to give something back to the community, why not start a translation of coppermine for your language?

These are the rules and guidelines for translation to help you get started.

## Why translate?

- To give something back to the community
- Because you needed the translation anyway...
- To see your name on the credits list
- To promote your services (being linked from a relevant page like the Coppermine team/credits page will increase your page rank as well)
- Because you're a nice person

## Translations for which languages are needed?

There are already several languages supported by coppermine; as the number of language-files for coppermine grows, there may be translations available that were not included into the package you downloaded. Before you actually start to work on a translation, look here:

- Is the language you're looking for already included in the lang-folder of the coppermine package you downloaded?
- Is the language file already available in the subversion repository? Visit http://svn.code.sf.net/p/coppermine/code/trunk/cpg1.5.x/lang/
- Has someone volunteered to do the translation recently on the Coppermine board thread "[Help wanted]: Translations for CPG1.5.x"? Please read the thread carefully to check if the translation has already been done or is in the works. We appreciate your intent, and we also value your time, so it'd be a pity if you and another translators went through all the work to submit two versions of the same language.
  You may find also find additional information there that didn't make it into this document ...

## Who can translate?

Anyone with a good grasp of a language can, but when a new version of coppermine is being prepped for released, the dev team will contact the translators of previous versions and ask them to translate for the new version, as well. These "original" translators are requested to advise the development team if they are willing and able to do the translation (before actual work on the translation starts). Languages previously assigned to those who respond that they're unable to do the "new" translation or those assigned to translators that fail to reply, over a prescribed time, will be placed on a list on "[Help wanted]: Translations for CPG1.5.x". Anyone who is interested and ready to help with the translation for these "orphaned" languages should reply to the thread and assign the translation to him/herself.

If you are fluent in a language that hasn't been translated yet and hasn't been assigned to anyone, please assign it to yourself.

## Character encoding

Many languages have special alphabets other than the latin set, or have additional characters (like ä ß à á â ã å æ ç þ ð ø). Many of these special chars have what are called html equivalents (e.g. &auml; for ä), but you must not use these html equivalents of your special language characters when doing your translations, as unwanted side-effects may appear with the usage of JavaScript!

No matter what encoding you use to contribute your translation, the encoding with which your translation contribution will be added to the package will be utf-8. In other words: some coppermine developer will have to transform your proprietary encoding to utf-8 before it can be used, so if you can you should use utf-8 in the first place.

Coppermine adds a charset meta tag to the header of each ouput file to instruct the browser how to render special chars. You should add the name of the charset you're using for your translation at the very start of the language file, e.g.

    $lang_charset = 'iso-8859-1';

. You can find a list of charsets at http://www.w3.org/International/O-charset-lang.html. Whenever possible, you shouldn't choose platform-dependant charset (e.g. windows-1252), but cross-platform ones (e.g. iso-8859-1).

You'll have noticed that coppermine language files come in utf-8 encoding. You do not have to concern yourself with the creation of the utf-8 version if you have no idea how to accomplish this - the dev team will take care of that. However, your language file will finally go into the package as UTF-8 file. Subsequently, if you want to create a perfect language file, create it in utf-8 in the first place.

## Editors & Tools

In fact you can use nearly any text editor you feel comfortable with that will allow you to save your text in the ANSI format - Windows Notepad (also known as "Editor" in Windows 2000/XP) will do just fine.

Of course, you're welcome to use a more powerfull editor and use (if you can) utf-8 as encoding.

To determine whether or not your favorite text editor can correctly handle the necessary encoding, start the translation by translating only a few lines (preferrably some that contain special chars from you language), save the translation file and close it. Then try to open it with a plain text editor on your system (e.g. Notepad) - if everything displays as expected, your editor should work fine.

The drawback when using one of the tools that come with the operating system Microsoft Windows out of the box is the fact that they haven't been created with Unicode (utf-8) support in mind, but mostly catter for the proprietary ANSI format that was introduced way back with MS DOS. Subseuqently, if you language is using non-latin characters you might have a hard time to test the language file in your testbed before submitting it.

Recommended Tools: to see what has changed between the language files of cpg1.4.x and cpg1.5.x, we recommend using a diff viewer that can highlight the differences in both files. Windows users should opt for the great, changes in file viewer WinMerge (available as freeware; 3 MB, localizations available as well): You can even edit the files with this tool (352 of 1152 lines have been added or changed). All new/changed lines have a comment at the end like this one: `//cpg1.5.x`.
If you need a powerfull, free editor for Windows, the dev team recommends using Notepad++.

For a full list of suggestions, please review "Tools recommended by the devs"

A text processor like MS Word is definitely not the right tool to handle a language file, as it tends to "beautify" the code within a language file, which will break the language file.

If you're concerned to install yet another tool on your operating system, then don't be alarmed: many of the editors (like Notepad++) come in packages that allow you to run the editor without installation: subsequently, your operating system doesn't get slowed down or cluttered by yet another application.

## Full translations only

Up until version 1.2 of coppermine we only sent out the lines that had changed in the language files from previous versions to the translators. Although this seemed to be a very easy solution and approach, we soon discovered that this method had severe drawbacks:

- The translators couldn't test their code immediately - if a single quote is missing from the language file, the entire file won't work
- Too often, corrections had to be sent back and forth between the dev team and the translators
- The dev team had to merge the previous language files with the bits that were newly translated - this resulted in an additional heavy workload for the dev team, slowing down the new release and keeping them from what they do best
- The translators didn't know the exact context that some lines appeared in, making it impossible to provide the proper translations

For these reasons we now provide the translators with the most recent english language file along with all existing language files of previous versions as references. Additionally we provide this guide that you are currently reading, asking them (the translators: you in this particular case) to translate the file in its entirety. Of course, you can (and are even encouraged to) take a look at the language files from older versions and adopt (port) the contents that are already in the old version whenever they apply.

This does of course not mean that you need to provide a full translation as much as the completeness of your contribution is concerned: we understand that it's a lot of work to come up with a translation for each string in a language file, that's why it's acceptable as well if you only provide a partial translation into your language, with part of the language file remaining in English. Please make sure though to tell us that you are providing a partial translation only.

## Step by step

Here are the detailed steps for translating coppermine language files:

1. open english.php with your text editor
2. Save the file immediately after opening under a different filename (to make sure you always have an unmodified english language file that can be used as a reference) - the filenames of the language files will decide how the language name will look in the dropdown list of the coppermine backend - use the english (roman characters) name of your language as the final filename, using lowercase in the name with no spaces or special chars (except "-" and "_" and the dot to mark the extension. If the language name itself isn't self-explanatory, add info with an underscore.
   Examples: german.php, italian.php, greek.php, brazilian_portuguese.php
3. Edit the header info (example content is highlighted):
   `// info about translators and translated language`
   `$lang_translation_info['lang_name_english'] = 'German';`The name of your language in English
   `$lang_translation_info['lang_name_native'] = 'Deutsch';`The name of your language in your mother tongue
   `$lang_translation_info['lang_country_code'] = 'de';`The country code representing your language. If your language is spoken in several countries, choose the one most people will relate to your language
   `$lang_translation_info['trans_name'] = 'GauGau';`Your name (or rather the name you would like to appear on the credits page)
   `$lang_translation_info['trans_email'] = '';`If you prefer, your email address, which would normally appear on the credits page, can be left blank
   `$lang_translation_info['trans_website'] = 'http://gaugau.de/';`Your website (goes to credit page). If you specify none, your profile page will be displayed instead
   `$lang_translation_info['trans_date'] = '2009-01-27';`The date you translated/last changed the language file
   `);`
   Fill in the data you want to appear on the credits page as shown in the example above.
4. The coppermine language file is used to dynamically replace php variables/arrays with the correct content. There are different ways those arrays are being filled - as shown in these examples (stuff that needs to be translated is highlighted):
   - `$lang_day_of_week = array('Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat');`A plain list of values in an array. Translate each word inside the quotes.
   - `$lang_yes = 'Yes';` A value is assigned to a variable. Translate everything inside the single quotes.
   - `$lang_common['keyword_separators'] = array(' '=>'space', ','=>'comma', ';'=>'semicolon');` An array with key => value pairs. Only translate the value, the key must be left alone!
     `'albums' => 'Albums',
     'pictures' => 'Files',
     );`
   - Cascaded/multi-dimensional arrays have been dropped from cpg1.4.x to cpg1.5.x, so you don't have to worry about them any longer.
   - Var definitions using the heredoc syntax: $lang_forgot_passwd_php['account_verify_email'] = <<< EOT You have requested a new password. If you would like to proceed with having a new password sent to you, click on the following link: <a href="{VERIFY_LINK}">{VERIFY_LINK}</a> Regards, The management of {SITE_NAME} EOT; Make sure to only translate the plain text, leaving everything in curled braces and all html tags intact

   Translate the entire language file as described - you'll find your way around in no time, even if you're not a seasoned PHP coder.

5. Test your translation: upload your language file to your server and browse your gallery, adding an additional parameter `lang=your_language_name` to the URL (e.g. `http://yoursite.tld/coppermine/?lang=german)`. Make sure to test as many aspects as possible from the file you created, especially in the creation, renaming and deleting of users,categories, albums, pictures and comments.
6. Proof-reading: if you can, let someone else (preferably non-tech user) test your translation as well. You might be surprised as to what they will discover...
7. Post your language as a zipped attachment of the thread "[Help wanted]: Translations for CPG1.5.x".
   You can post the attachment as a txt file or you can put it inside of a .zip archive, but please don't use other exotic archival formats such as .rar, .ace, etc.

## Special issues

### Escaping single quotes

As you may have already noticed, all translation strings are contained between a pair of single quotes or apostrophes - this is the proper method used in PHP. Therefore, if you want your translation to actually contain a single quote (apostrophe), you must "instruct" PHP that the apostrophe (single quote) contained in a text string is part of the string and not the end of the string. For this purpose, a backslash (\) is used to instruct PHP that the character immediately following it is a "string" character and not part of the PHP code, itself. This is called escaping a character in programing languages. PHP uses the backslash (\) to escape characters, that's why care must be taken to not do this:

`$lang_errors['access_denied'] = 'You don't have permission to access this page.';`
but, to do this, instead:
`$lang_errors['access_denied'] = 'You don\'t have permission to access this page.';`

### Single quotes in JavaScript (//js-alert)

Things are a bit more complicated if the output is to be used not only in plain HTML, but in JavaScript, as well. Single quotes that appear in the HTML output of the language file must also be escaped for use in any JavaScript routine with a backslash as well. That's why specific lines in the language file that will be used as JavaScript in Coppermine's output have been tagged with a comment at the end of the line, which reads: `//js-alert`. If you intend to have a single quote in the final output, you'll have to add 3 backslashes in front of the single quote, as in this example:

    'no_change' => 'Vous n\\\'avez effectué aucun changement !', //js-alert

### Placeholders with " % "

You'll also notice that in several places of the language file, there are text that contain a percent-sign (%), followed immediately by a letter. Those combinations must not be translated or separated - they are there intentionally and are used later as specifier arguments, or calls, for variable replacement and/or formating that needs to take place.

`$lang_rate_pic['rating'] = '(Current rating : %s / %s with %s votes)';`

What actually happens is that in the code (usually using the PHP command sprintf; refer to the type specifier specifications for details) there is a replacement, where the placeholder (usually `%s`) is being replaced with some content dynamically.

## Language versions

### Found a typo/spelling error?

Maybe a translation for your language has already been done, but you're not happy with it: if there are bugs (spelling errors etc.), first check the download section to see if a fixed (updated) version has already been submitted. If not, report your finding(s) on the board along with your suggestion for a fix, like this:

in lang/yourlanguage.php search for
`$lang_example['some_definition'] = 'bar foo';`
and replace with
`$lang_example['some_definition'] = 'foo bar',`

### Another translation?

Everybody who knows languages knows that there is no such thing as "one correct translation" - there are always differences in the way we to translate expressions, or whole sentences. Maybe you feel that an existing version of your language file doesn't suit your purpose; perhaps the translator had another audience/target group in mind, or you want a more formal translation (in many languages there are signifcant difference in grammar and expression between formal and casual speech or text).
Please do not flame (berate) the original translator on the board, but provide an alternative translation along with details on what you changed and for what target audience your version is intended.

## Work in progress

Coppermine, like everything else online, is a work in progress. Your copy of the english.php (that should always be used as the base reference file for your translation) may already be outdated. That's why it is critical that you always refer to the Subversion-Repository Language Section to make sure that you have the most recent english language file (translator version) on hand before starting your translation (and maybe even the most updated version of this document, as well, as there may be many questions along the way that need to be addressed in this document after the initial release of this document). Remember: if an option/replacement string is not translated, it will not be visible in your language at all.

## Initial translation for release

When preparing for a release, the dev team sets up a feature freeze to allow the translators to submit their translations, halting the coppermine development during that period. If you're willing to translate, do so as soon as possible and send your translation back immediately to ensure that the new version of coppermine can be released with your language file.

## Using older language files

We understand that coming up with a full translation can be quite a difficult task to accomplish, so you might be tenpted to skip the hard work and go for a solution that may seem to be easier at first sight: you might want to use a language file that was created for a previous version of coppermine (e.g. cpg1.4.x) and built on that file (instead of doing as suggested in this section of the docs and starting your work based on the current version of `lang/english.php`).

Although the "lazy" method may seem to be attractive, you can't use it for various reasons. To mention only a few of them:

- The way the language file arrays are defined has changed from

      $lang_meta_album_names = array(
        'random' => 'Random files',
        'lastup' => 'Last additions',
        'lastalb'=> 'Last updated albums',
        'lastcom' => 'Last comments',
        'topn' => 'Most viewed',
        'toprated' => 'Top rated',
        'lasthits' => 'Last viewed',
        'search' => 'Search results',
        'favpics'=> 'Favorite Files',  //cpg1.4
      );

  to

      $lang_meta_album_names['random'] = 'Random files';
      $lang_meta_album_names['lastup'] = 'Last additions';
      $lang_meta_album_names['lastalb'] = 'Last updated albums';
      $lang_meta_album_names['lastcom'] = 'Last comments';
      $lang_meta_album_names['topn'] = 'Most viewed';
      $lang_meta_album_names['toprated'] = 'Top rated';
      $lang_meta_album_names['lasthits'] = 'Last viewed';
      $lang_meta_album_names['search'] = 'Image search results';
      $lang_meta_album_names['album_search'] = 'Album search results';
      $lang_meta_album_names['category_search'] = 'Category search results';
      $lang_meta_album_names['favpics'] = 'Favorite files';
      $lang_meta_album_names['datebrowse'] = 'Browse by date'; //cpg1.5

- varaibles names have changed (i.e. `$album_date_fmt = '%B %d, %Y';` was changed to `$lang_date['album'] = '%B %d, %Y';`
- The entire definition of array for the config section was changed completely.

This should make clear that you should not start editing a language file for cpg1.4.x and try to port that for cpg1.5.x - you'd have to perform edits for each and every line.

Instead, we recommend doing as suggested and using a copy of english.php from cpg1.5.x and use that as a base for your new translation. We recommend to open a copy of the outdated language file as well in your editor and just copy individual strings from the outdated language file to your fresh copy.

## Translating the documentation

As suggested above, all contributions are welcome. While it already is a huge task to come up with a coppermine language file, it's even a greater task to come up with a full translation of the coppermine documentation. That's one of the reasons why the documentation that used to be one monolithic block (one huge HTML page) has been split up into separate files starting with cpg1.5.x.

For the benfit of your community, you're asked to translate part of the documentation (or maybe even all of it) as well. To accomplish this, do the same as suggested above: make sure that your translation doesn't already exist by checking the SVN repository and if there already is a discussion on the forums going on. If there is no such activity, go ahead and start your translation.

### Steps for translating the docs into your language

- #### Make sure that the translation doesn't already exist

  As suggested above, make sure that you don't have to spend double effort on this - always check the SVN repository and the corresponding board sections before starting

- #### Create the structure

  Your translation will later go into a sub-folder (that represents the language code) of the docs folder, so you should create a folder within your local copy of coppermine (inside the docs folder) if this doesn't already exist - there might be a partial translation already, so you'll only need to create the sub-folder if it doesn't already exist). If you're for example about to create an hungarian translation, create a sub-folder in the docs folder that is named `hu`. Within this new folder, create a sub-folder named `images` (no matter if the word for "images" differs in your language - after all, it's just a folder name that won't matter much to others). The images-folder will later contain your screenshots.

- #### Copy the core language files

  Copy the basic files from the english documents folder (`your_local_coppermine_folder/docs/en/`) into your newly-created language folder (in above example for hungarian, this would be `your_local_coppermine_folder/docs/hu/`). The files you absolutely need to copy and edit later are `index.htm`, `script.js` and `toc.htm`, but if you plan to do a full translation, you might as well copy all files from the `en`-folder. Of course this step only applies if there is no partial translation existing. If there already are files in your language folder, don't copy the files from the english folder, but use the existing ones (as suggested later).

- #### Start translating

  You should first start translating the very first page of the docs (`index.htm`) using a plain text editor. Alternatively, you could use a diff-viewer, so you always have the English original and your translation side-by-side.

- #### Areas to pay attention to

  - Leave the line `<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en" dir="ltr">` alone! Do not make it match your language - this is a part of the XHTML-specification, not some meta-information on your document language
  - However, do translate the title-tag (something like `<title>Section or chapter name - Coppermine Photo Gallery - Documentation & Manual</title>`)
  - For search engine friendliness, you should edit the line `<meta name="language" content="en" />` - the content ("en") should be replaced with the language code for your language. If you're not sure, leave it as-is (a coppermine dev will take care of this after you have contributed).
  - Edit the meta description (`<meta name="description" content="...">`) as well to come up with a short summary what the page is about (in your language).
  - Leave the file names alone: do not translate the files names!
  - Leave the anchor names alone: don't edit anchor names (like `<a name="copyright"></a>`), even if the word "copyright" in this example doesn't mean the same thing (or anything at all) in your language.
    This is meant to make sure that supporters and users can easily refer to doc sections they don't even understand.
  - Leave the JavaScript-sections alone: they are used to provide the navigation later - don't touch them. Especially the line `dateRevision(' $LastChangedDate: 2015-11-18 16:07:18 +0100 (Wed, 18 Nov 2015) $ ', ' $Revision: 8830 $ ');` or similar is not meant to be edited by you: it will be updated when your contribution is being added to the package.
  - Do not edit the SVN version info section at the top of the page (commented out) - it will be used for internal purposes (again: subversion repository) later.
  - Don't improve your localized version/translation only: you might find that the English part of the documentation is lacking some explanations or that it is inacurate or missing important bits, so you might be tempted to add sections to your translation of the docs that don't exist in the original, English section of the docs. However, we don't think that this is a good idea: if you have suggestions to make how to improve the docs, we'd love to see your suggestion for the benefit of all users. This being said: please don't just add sections to your local copy of the translation - post your suggestion publicly instead in order to see your proposed improvement go into both the English version of the docs as well as your version.
  - Translate examples if applicable: you are welcome to translate examples into your language as well: the English sample user name "John Doe" can of course be changed into the typical German sample user "Max Mustermann" for example. The sample URL `http://yoursite.tld/your_coppermine_folder/` can of course be translated into `http://deine-seite.tld/dein_coppermine_verzeichnis/` in a German localization of the docs.
  - Once you have started translating a documentation file, you can savely replace the line <div id="doc_en_only">No translation available</div> with <div id="doc_en_partial">Partial translation</div>
  - After having completed your translation of a documentation page, please remove the line <div id="doc_en_only">No translation available</div> or <div id="doc_en_partial">Partial translation</div> completely.

- #### Take care of the table of contents

  Once you have completed translating the files you want to translate (in an ideal world: all files), take a look at the files `script.js` and `toc.htm`. The former file is the JavaScript file that will later compose the menu/navigation on all pages, the later file will be the plain HTML equivalent (for those who have JavaScript disabled).
  In script.js, scroll a bit down until you find the navigational structure (starting with the line `var doc_toc = '';` - each of the following lines is representing a navigation item. You should translate this as well (at least the stuff you have come up with). Of course, you don't have to edit the file names (they should remain in English), but only the textual representation. If you're not sure what to do, take a look at an existing translation and see how this has been done there.
  The similar thing applies to toc.htm, which is the HTML-driven "table of contents"; again, you should translate the labels, but not the file names nor the anchor names.
- There are some strings inside script.js that need to be translated as well: search for
  - `$('#docheader').text('Coppermine Photo Gallery v1.5.x: Documentation and Manual');` and replace the actual text in that line (`Documentation and Manual`) with the translation into your language. The function definition for `cpgDocHeader` contains the strings that are used to replace the existing placeholders in the header of the file.
  - The function definition for `cpgDocFooter` determines how the "Back to top" at the bottom of each documentation page is being localized, so you should replace that string with the translation for your language. Find `overall_doc_footer += '<a href="#top">Back to Top</a>';` and replace the actual text in that line (`Back to Top`) with the translation into your language
  - The function definition for `dateRevision` contains some strings that need to be translated and other that need to be preserved, so you need to be extra carefull with that function. Find `$('#doc_last_changed').text('About this document: ' + 'last changed on ' + lastChangeDate);` and replace the actual text in that line (`About this document` and `last changed on`, but not `lastChangeDate`) with the translation into your language
  - `$('#doc_revision').text(', SVN revision ' + revisionNumber);` and replace the actual text in that line (`SVN revision`) with the translation into your language. If you're not sure what a SVN revision is, leave that line alone!
  - The function `cpgDocSearch` determines the localisation of the search engine. However, it requires the Coppermine dev team members to create a custom search engine in advance, that's why you (as a translator) shouldn't touch that function at all
  - The function `cpgDocTranslationWarning` doesn't do anything in the English branch of the documentation. It needs to be edited in your copy of the documentation, replacing the strings in quotes.

- #### Zip your translation

  Finally, when you're done translating, zip your custom language folder and attach the zip to a posting on the corresponding coppermine board. Of course, there will be a credit list where your name and site address will be mentioned, so make sure to provide the details you want to see go into that credit list within your posting.

## Further reading

- The absolute minimum every software developer absolutely, positively must know about unicode and character sets by Joel Spolsky