Просмотр исходного кода

[DOCUMENTATION] English:

- manual fixes

git-svn-id: http://framework.zend.com/svn/framework/standard/trunk@16450 44c647ce-9c0f-0410-b52a-842ac1e357ba
thomas 16 лет назад
Родитель
Сommit
83d956db29

+ 25 - 0
documentation/manual/en/module_specs/Zend_Filter-Migration.xml

@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Reviewed: no -->
+<sect1 id="zend.filter.migration">
+    <title>Migrating from Previous Versions</title>
+
+    <para>
+        This chapter documents primarily backwards compatibility breaks made in
+        Zend_Filter, and should serve to aid in migration from previous versions.
+    </para>
+
+    <sect2 id="zend.filter.migration.zf2105">
+        <title>Migrating from versions prior to 1.9</title>
+
+        <para>
+            Prior to the 1.9 release, <classname>Zend_Filter</classname> allowed
+            the usage of the static <methodname>get()</methodname> method. As with
+            release 1.9 this method has been renamed to
+            <methodname>filterStatic()</methodname> to be more descriptive. The
+            old <methodname>get()</methodname> method is marked as depreciated.
+        </para>
+    </sect2>
+</sect1>
+<!--
+vim:se ts=4 sw=4 et:
+-->

+ 8 - 8
documentation/manual/en/module_specs/Zend_Filter.xml

@@ -80,7 +80,7 @@ echo $htmlEntities->filter('"'); // &quot;
         <para>
             If it is inconvenient to load a given filter class and create an
             instance of the filter, you can use the static method
-            <classname>Zend_Filter::get()</classname> as an alternative invocation style.
+            <classname>Zend_Filter::filterStatic()</classname> as an alternative invocation style.
             The first argument of this method is a data input value, that you
             would pass to the <code>filter()</code> method. The second
             argument is a string, which corresponds to the basename of the
@@ -90,7 +90,7 @@ echo $htmlEntities->filter('"'); // &quot;
             input.
 
             <programlisting language="php"><![CDATA[
-echo Zend_Filter::get('&', 'HtmlEntities');
+echo Zend_Filter::filterStatic('&', 'HtmlEntities');
 ]]></programlisting>
 
         </para>
@@ -100,7 +100,7 @@ echo Zend_Filter::get('&', 'HtmlEntities');
             are needed for the filter class.
 
             <programlisting language="php"><![CDATA[
-echo Zend_Filter::get('"', 'HtmlEntities', array(ENT_QUOTES));
+echo Zend_Filter::filterStatic('"', 'HtmlEntities', array(ENT_QUOTES));
 ]]></programlisting>
 
         </para>
@@ -125,12 +125,12 @@ echo Zend_Filter::get('"', 'HtmlEntities', array(ENT_QUOTES));
 
             <para>
                 When working with self defined filters you can give a forth parameter
-                to <methodname>Zend_Filter::get()</methodname> which is the namespace
+                to <methodname>Zend_Filter::filterStatic()</methodname> which is the namespace
                 where your filter can be found.
             </para>
 
             <programlisting language="php"><![CDATA[
-echo Zend_Filter::get(
+echo Zend_Filter::filterStatic(
     '"',
     'MyFilter',
     array($parameters),
@@ -141,14 +141,14 @@ echo Zend_Filter::get(
             <para>
                 <classname>Zend_Filter</classname> allows also to set namespaces as default.
                 This means that you can set them once in your bootstrap and have not to give
-                them again for each call of <methodname>Zend_Filter::get()</methodname>. The
+                them again for each call of <methodname>Zend_Filter::filterStatic()</methodname>. The
                 following code snippet is identical to the above one.
             </para>
 
             <programlisting language="php"><![CDATA[
 Zend_Filter::setDefaultNamespaces(array('FirstNamespace', 'SecondNamespace'));
-echo Zend_Filter::get('"', 'MyFilter', array($parameters));
-echo Zend_Filter::get('"', 'OtherFilter', array($parameters));
+echo Zend_Filter::filterStatic('"', 'MyFilter', array($parameters));
+echo Zend_Filter::filterStatic('"', 'OtherFilter', array($parameters));
 ]]></programlisting>
 
             <para>

+ 742 - 0
documentation/manual/en/module_specs/Zend_Translate-Additional.xml

@@ -0,0 +1,742 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Reviewed: no -->
+<sect1 id="zend.translate.additional">
+
+    <title>Additional features for translation</title>
+
+    <para>
+        There are several additional features which are supported by
+        <classname>Zend_Translate</classname>. Read here for these additional informations.
+    </para>
+
+    <sect2 id="zend.translate.additional.options">
+
+        <title>Options for adapters</title>
+
+        <para>
+            Options can be used with all adapters. Of course the options are different for all adapters.
+            You can set options when you create the adapter. Actually there is one option which is available
+            to all adapters: '<code>clear</code>' sets if translation data should be added to existing
+            one or not. Standard behaviour is to add new translation data to existing one. But the
+            translation data is only cleared for the selected language. So other languages remain
+            untouched.
+        </para>
+
+        <para>
+            You can set options temporarily when using <code>addTranslation($data, $locale, array $options = array())</code>
+            as third and optional parameter. And you can use the method <code>setOptions()</code> to
+            set the options permanently.
+        </para>
+
+        <example id="zend.translate..additional.options.example">
+            <title>Using translation options</title>
+            <programlisting role="php"><![CDATA[
+// define ':' as separator for the translation source files
+$options = array('delimiter' => ':');
+$translate = new Zend_Translate(
+    'csv',
+    '/path/to/mytranslation.csv',
+    'de',
+    $options);
+
+...
+
+// clear the defined language and use new translation data
+$options = array('clear' => true);
+$translate->addTranslation('/path/to/new.csv', 'fr', $options);
+]]></programlisting>
+        </example>
+
+        <para>
+            Here you can find all available options for the different adapters with a description of their usage:
+        </para>
+
+        <table id="zend.translate.additional.options.alloptions">
+            <title>Options for translation adapters</title>
+            <tgroup cols="4">
+                <thead>
+                    <row>
+                        <entry>Option</entry>
+                        <entry>Adapter</entry>
+                        <entry>Description</entry>
+                        <entry>Default value</entry>
+                    </row>
+                </thead>
+                <tbody>
+                    <row>
+                        <entry>clear</entry>
+                        <entry>all</entry>
+                        <entry>
+                            If set to true, the already read translations will be cleared. This can be used
+                            instead of creating a new instance when reading new translation data
+                        </entry>
+                        <entry><emphasis>false</emphasis></entry>
+                    </row>
+                    <row>
+                        <entry>disableNotices</entry>
+                        <entry>all</entry>
+                        <entry>
+                            If set to true, all notices regarding not available translations will be
+                            disabled. You should set this option to true in production environment
+                        </entry>
+                        <entry><emphasis>false</emphasis></entry>
+                    </row>
+                    <row>
+                        <entry>ignore</entry>
+                        <entry>all</entry>
+                        <entry>
+                            All directories and files beginning with this prefix will be ignored when
+                            searching for files. This value defaults to <emphasis>'.'</emphasis>
+                            which leads to the behavior that all hidden files will be ignored. Setting this
+                            value to <code>'tmp'</code> would mean that directories and files like
+                            <code>'tmpImages'</code> and <code>'tmpFiles'</code>
+                            would be ignored as well as all subsequent directories
+                        </entry>
+                        <entry><emphasis>.</emphasis></entry>
+                    </row>
+                    <row>
+                        <entry>log</entry>
+                        <entry>all</entry>
+                        <entry>
+                            An instance of <classname>Zend_Log</classname> where untranslated messages and notices will be
+                            written to
+                        </entry>
+                        <entry><emphasis>null</emphasis></entry>
+                    </row>
+                    <row>
+                        <entry>logMessage</entry>
+                        <entry>all</entry>
+                        <entry>
+                            The message which will be written into the log
+                        </entry>
+                        <entry><emphasis>Untranslated message within '%locale%': %message%</emphasis></entry>
+                    </row>
+                    <row>
+                        <entry>logUntranslated</entry>
+                        <entry>all</entry>
+                        <entry>
+                            When this option is set to true, all message IDs which can not be
+                            translated will be written into the attached log
+                        </entry>
+                        <entry><emphasis>false</emphasis></entry>
+                    </row>
+                    <row>
+                        <entry>scan</entry>
+                        <entry>all</entry>
+                        <entry>
+                            If set to null, no scanning of the directory structure will be done.
+                            If set to <classname>Zend_Translate::LOCALE_DIRECTORY</classname> the locale will be detected within the
+                            directory. If set to <classname>Zend_Translate::LOCALE_FILENAME</classname> the locale will be detected
+                            within the filename. See <xref linkend="zend.translate.additional.detection" />
+                            for details
+                        </entry>
+                        <entry><emphasis>null</emphasis></entry>
+                    </row>
+                    <row>
+                        <entry>delimiter</entry>
+                        <entry>Csv</entry>
+                        <entry>Defines which sign is used as delimiter for separating source and translation</entry>
+                        <entry><emphasis>;</emphasis></entry>
+                    </row>
+                    <row>
+                        <entry>enclosure</entry>
+                        <entry>Csv</entry>
+                        <entry>Defines the enclosure character to be used. Defaults to a doublequote</entry>
+                        <entry><emphasis>"</emphasis></entry>
+                    </row>
+                    <row>
+                        <entry>length</entry>
+                        <entry>Csv</entry>
+                        <entry>Defines the maximum length of a csv line. When set to 0 it will be detected automatically</entry>
+                        <entry><emphasis>0</emphasis></entry>
+                    </row>
+                </tbody>
+            </tgroup>
+        </table>
+
+        <para>
+            When you want to have self defined options, you are also able to use them within all adapters.
+            The <code>setOptions()</code> method can be used to define your option. <code>setOptions()</code>
+            needs an array with the options you want to set. If an given option exists it will be signed over.
+            You can define as much options as needed as they will not be checked by the adapter. Just make sure
+            not to overwrite any existing option which is used by an adapter.
+        </para>
+
+        <para>
+            To return the option you can use the <code>getOptions()</code> method. When <code>getOptions()</code>
+            is called without a parameter it will return all options set. When the optional parameter is given
+            you will only get the specified option.
+        </para>
+
+    </sect2>
+
+    <sect2 id="zend.translate.additional.languages">
+
+        <title>Handling languages</title>
+
+        <para>
+            When working with different languages there are a few methods which will be useful.
+        </para>
+
+        <para>
+            The <code>getLocale()</code> method can be used to get the currently set language. It can either hold
+            an instance of <classname>Zend_Locale</classname> or the identifier of a locale.
+        </para>
+
+        <para>
+            The <code>setLocale()</code> method sets a new standard language for translation. This prevents the
+            need of setting the optional language parameter more than once to the <code>translate()</code> method.
+            If the given language does not exist, or no translation data is available for the language,
+            <code>setLocale()</code> tries to downgrade to the language without the region if any was given.
+            A language of <code>en_US</code> would be downgraded to <code>en</code>. When even the downgraded
+            language can not be found an exception will be thrown.
+        </para>
+
+        <para>
+            The <code>isAvailable()</code> method checks if a given language is already available. It returns
+            <constant>TRUE</constant> if data for the given language exist.
+        </para>
+
+        <para>
+            And finally the <code>getList()</code> method can be used to get all currently set languages for an adapter
+            returned as array.
+        </para>
+
+        <example id="zend.translate.additional.languages.example">
+            <title>Handling languages with adapters</title>
+            <programlisting role="php"><![CDATA[
+// returns the currently set language
+$actual = $translate->getLocale();
+
+// you can use the optional parameter while translating
+echo $translate->_("my_text", "fr");
+// or set a new language
+$translate->setLocale("fr");
+echo $translate->_("my_text");
+// refer to the base language
+// fr_CH will be downgraded to fr
+$translate->setLocale("fr_CH");
+echo $translate->_("my_text");
+
+// check if this language exist
+if ($translate->isAvailable("fr")) {
+    // language exists
+}
+]]></programlisting>
+        </example>
+
+        <sect3 id="zend.translate.additional.languages.automatic">
+
+            <title>Automatical handling of languages</title>
+
+            <para>
+                Note that as long as you only add new translation sources with the <code>addTranslation()</code>
+                method <classname>Zend_Translate</classname> will automatically set the best fitting language for your
+                environment when you use one of the automatic locales which are '<code>auto</code>' or '<code>browser</code>'. So
+                normally you will not need to call <code>setLocale()</code>. This should only be used in
+                conjunction with automatic source detection.
+            </para>
+
+            <para>
+                The algorithm will search for the best fitting locale depending on the user's browser and
+                your environment. See the following example for details:
+            </para>
+
+            <example id="zend.translate.additional.languages.automatic.example">
+                <title>Automatically language detection</title>
+                <programlisting role="php"><![CDATA[
+// Let's expect the browser returns these language settings:
+// HTTP_ACCEPT_LANGUAGE = "de_AT=1;fr=1;en_US=0.8";
+
+// Example 1:
+// When no fitting language is found, the message ID is returned
+$translate = new Zend_Translate(
+    'gettext',
+    'my_it.mo',
+    'auto',
+    array('scan' => Zend_Translate::LOCALE_FILENAME));
+
+// Example 2:
+// Best found fitting language is 'fr'
+$translate = new Zend_Translate(
+    'gettext',
+    'my_fr.mo',
+    'auto',
+    array('scan' => Zend_Translate::LOCALE_FILENAME));
+
+// Example 3:
+// Best found fitting language is 'de' ('de_AT' will be degraded)
+$translate = new Zend_Translate(
+    'gettext',
+    'my_de.mo',
+    'auto',
+    array('scan' => Zend_Translate::LOCALE_FILENAME));
+
+// Example 4:
+// Returns 'it' as translation source and overrides the automatic settings
+$translate = new Zend_Translate(
+    'gettext',
+    'my_it.mo',
+    'auto',
+    array('scan' => Zend_Translate::LOCALE_FILENAME));
+
+$translate->addTranslation('my_ru.mo', 'ru');
+$translate->setLocale('it_IT');
+]]></programlisting>
+            </example>
+
+            <para>
+                After setting a language manually with the <code>setLocale()</code> method the automatic
+                detection will be switched off and overridden.
+            </para>
+
+            <para>
+                If you want to use it again, you can set the language
+                <emphasis>auto</emphasis> with <code>setLocale()</code> which will reactivate
+                the automatic detection for <classname>Zend_Translate</classname>.
+            </para>
+
+            <para>
+                Since Zend Framework 1.7.0 <classname>Zend_Translate</classname> also recognises an application
+                wide locale. You can simply set a <classname>Zend_Locale</classname> instance to the registry like shown
+                below. With this notation you can forget about setting the locale manually with each instance
+                when you want to use the same locale multiple times.
+            </para>
+
+            <programlisting role="php"><![CDATA[
+// in your bootstrap file
+$locale = new Zend_Locale();
+Zend_Registry::set('Zend_Locale', $locale);
+
+// default language when requested language is not available
+$defaultlanguage = 'en';
+
+// somewhere in your application
+$translate = new Zend_Translate('gettext', 'my_de.mo');
+
+if (!$translate->isAvailable($locale->getLanguage())) {
+    // not available languages are rerouted to another language
+    $translate->setLocale($defaultlanguage);
+}
+
+$translate->getLocale();
+]]></programlisting>
+
+        </sect3>
+
+    </sect2>
+
+    <sect2 id="zend.translate.additional.detection">
+
+        <title>Automatic source detection</title>
+
+        <para>
+            <classname>Zend_Translate</classname> can detect translation sources automatically. So you don't have
+            to declare each source file manually. You can let <classname>Zend_Translate</classname> do this job and
+            scan the complete directory structure for source files.
+        </para>
+
+        <note>
+            <para>
+                Automatic source detection is available since Zend Framework version 1.5 .
+            </para>
+        </note>
+
+        <para>
+            The usage is quite the same as initiating a single translation source with one difference.
+            You must give a directory which has to be scanned instead a file.
+        </para>
+
+        <example id="zend.translate.additional.languages.directory.example">
+            <title>Scanning a directory structure for sources</title>
+            <programlisting role="php"><![CDATA[
+// assuming we have the following structure
+//  /language/
+//  /language/login/login.tmx
+//  /language/logout/logout.tmx
+//  /language/error/loginerror.tmx
+//  /language/error/logouterror.tmx
+
+$translate = new Zend_Translate('tmx', '/language');
+]]></programlisting>
+        </example>
+
+        <para>
+            So <classname>Zend_Translate</classname> does not only search the given directory, but also all subdirectories for
+            translation source files. This makes the usage quite simple. But <classname>Zend_Translate</classname> will ignore all
+            files which are not sources or which produce failures while reading the translation data. So you
+            have to make sure that all of your translation sources are correct and readable because you will
+            not get any failure if a file is bogus or can not be read.
+        </para>
+
+        <note>
+            <para>
+                Depending on how deep your directory structure is and how much files are within this structure
+                it can take a long time for <classname>Zend_Translate</classname> to complete.
+            </para>
+        </note>
+
+        <para>
+            In our example we have used the TMX format which includes the language to be used within the
+            source. But many of the other source formats are not able to include the language within the
+            file. Even this sources can be used with automatic scanning if you do some pre-requisits as
+            described below:
+        </para>
+
+        <sect3 id="zend.translate.additional.detection.directory">
+
+            <title>Language through naming directories</title>
+
+            <para>
+                One way to include automatic language detection is to name the directories related to the
+                language which is used for the sources within this directory. This is the easiest way and
+                is used for example within standard gettext implementations.
+            </para>
+
+            <para>
+                <classname>Zend_Translate</classname> needs the '<code>scan</code>' option to know that it should search the names of all
+                directories for languages. See the following example for details:
+            </para>
+
+            <example id="zend.translate.additional.detection.directory.example">
+                <title>Directory scanning for languages</title>
+                <programlisting role="php"><![CDATA[
+// assuming we have the following structure
+//  /language/
+//  /language/de/login/login.mo
+//  /language/de/error/loginerror.mo
+//  /language/en/login/login.mo
+//  /language/en/error/loginerror.mo
+
+$translate = new Zend_Translate(
+    'gettext',
+    '/language',
+    null,
+    array('scan' => Zend_Translate::LOCALE_DIRECTORY));
+]]></programlisting>
+            </example>
+
+            <note>
+                <para>
+                    This works only for adapters which do not include the language within the source file.
+                    Using this option for example with TMX will be ignored. Also language definitions within
+                    the filename will be ignored when using this option.
+                </para>
+            </note>
+
+            <note>
+                <para>
+                    You should be aware if you have several subdirectories under the same
+                    structure. Assuming we have a structure like
+                    <code>/language/module/de/en/file.mo</code>. In this case the path contains
+                    multiple strings which would be detected as locale. It could be either
+                    <code>de</code> or <code>en</code>. In such a case the behaviour is
+                    undefined and it is recommended to use file detection in such situations.
+                </para>
+            </note>
+
+        </sect3>
+
+        <sect3 id="zend.translate.additional.detection.filename">
+
+            <title>Language through filenames</title>
+
+            <para>
+                Another way to detect the language automatically is to use special filenames. You can either
+                name the complete file or parts of a file after the used language. To use this way of detection
+                you will have to set the '<code>scan</code>' option at initiation. There are several ways of naming the
+                sourcefiles which are described below:
+            </para>
+
+            <example id="zend.translate.additional.detection.filename.example">
+                <title>Filename scanning for languages</title>
+                <programlisting role="php"><![CDATA[
+// assuming we have the following structure
+//  /language/
+//  /language/login/login_en.mo
+//  /language/login/login_de.mo
+//  /language/error/loginerror_en.mo
+//  /language/error/loginerror_de.mo
+
+$translate = new Zend_Translate(
+    'gettext',
+    '/language',
+    null,
+    array('scan' => Zend_Translate::LOCALE_FILENAME));
+]]></programlisting>
+            </example>
+
+            <sect4 id="zend.translate.additional.detection.filename.complete">
+
+                <title>Complete filename</title>
+
+                <para>
+                    Having the whole file named after the language is the simplest way but only viable
+                    if you have only one file per language.
+                </para>
+
+                <programlisting language="txt"><![CDATA[
+/languages/
+/languages/en.mo
+/languages/de.mo
+/languages/es.mo
+]]></programlisting>
+
+            </sect4>
+
+            <sect4 id="zend.translate.additional.detection.filename.extension">
+
+                <title>Extension of the file</title>
+
+                <para>
+                    Another simple way to use the extension of the file for language detection.
+                    But this may be confusing since you will no longer have an idea which extension the file
+                    originally had.
+                </para>
+
+                <programlisting language="txt"><![CDATA[
+/languages/
+/languages/view.en
+/languages/view.de
+/languages/view.es
+]]></programlisting>
+
+            </sect4>
+
+            <sect4 id="zend.translate.additional.detection.filename.token">
+
+                <title>Filename tokens</title>
+
+                <para>
+                    <classname>Zend_Translate</classname> is also capable of detecting the language if it is included within the
+                    filename. But if you go this way you will have to separate the language with a token.
+                    There are three supported tokens which can be used: a dot '.', an underscore '_', or
+                    a hyphen '-'.
+                </para>
+
+                <programlisting language="txt"><![CDATA[
+/languages/
+/languages/view_en.mo -> detects english
+/languages/view_de.mo -> detects german
+/languages/view_it.mo -> detects italian
+]]></programlisting>
+
+                <para>
+                    The first found string delimited by a token which can be interpreted as a locale will be used. See the following
+                    example for details.
+                </para>
+
+                <programlisting language="txt"><![CDATA[
+/languages/
+/languages/view_en_de.mo -> detects english
+/languages/view_en_es.mo -> detects english and overwrites the first file
+/languages/view_it_it.mo -> detects italian
+]]></programlisting>
+
+                <para>
+                    All three tokens are used to detect the locale. When the filename contains multiple tokens,
+                    the first found token depends on the order of the tokens which are used. See the following
+                    example for details.
+                </para>
+
+                <programlisting language="txt"><![CDATA[
+/languages/
+/languages/view_en-it.mo -> detects english because '_' will be used before '-'
+/languages/view-en_it.mo -> detects italian because '_' will be used before '-'
+/languages/view_en.it.mo -> detects italian because '.' will be used before '_'
+]]></programlisting>
+
+            </sect4>
+
+        </sect3>
+
+    </sect2>
+
+    <sect2 id="zend.translate.additional.istranslated">
+
+        <title>Checking for translations</title>
+
+        <para>
+            Normally text will be translated without any computation. But sometimes it is necessary to
+            know if a text is translated or not, therefor the <code>isTranslated()</code>
+            method can be used.
+        </para>
+
+        <para>
+            <code>isTranslated($messageId, $original = false, $locale = null)</code> takes
+            the text you want to check as its first parameter, and as optional third parameter the locale
+            for which you want to do the check. The optional second parameter declares whether translation
+            is fixed to the declared language or a lower set of translations can be used. If you have a text which
+            can be returned for 'en' but not for 'en_US' you will normally get the translation returned, but by
+            setting <code>$original</code> to true, <code>isTranslated()</code> will return false.
+        </para>
+
+        <example id="zend.translate.additional.istranslated.example">
+            <title>Checking if a text is translatable</title>
+            <programlisting role="php"><![CDATA[
+$english = array(
+    'message1' => 'Nachricht 1',
+    'message2' => 'Nachricht 2',
+    'message3' => 'Nachricht 3');
+
+$translate = new Zend_Translate('array', $english, 'de_AT');
+
+if ($translate->isTranslated('message1')) {
+    print "'message1' can be translated";
+}
+
+if (!($translate->isTranslated('message1', true, 'de'))) {
+    print "'message1' can not be translated to 'de'"
+        . " as it's available only in 'de_AT'";
+}
+
+if ($translate->isTranslated('message1', false, 'de')) {
+    print "'message1' can be translated in 'de_AT' as it falls back to 'de'";
+}
+]]></programlisting>
+        </example>
+
+    </sect2>
+
+    <sect2 id="zend.translate.additional.logging">
+
+        <title>How to log not found translations</title>
+
+        <para>
+            When you have a bigger site or you are creating the translation files manually, you often have
+            the problem that some messages are not translated. But there is an easy solution for you when you
+            are using <classname>Zend_Translate</classname>.
+        </para>
+
+        <para>
+            You have to follow two or three simple steps. First, you have to create an instance of
+            <classname>Zend_Log</classname>. Then you have to attach this instance to <classname>Zend_Translate</classname>.
+            See the following example:
+        </para>
+
+        <example id="zend.translate.additional.logging.example">
+            <title>Log translations</title>
+            <programlisting role="php"><![CDATA[
+$translate = new Zend_Translate('gettext', $path, 'de');
+
+// Create a log instance
+$writer = new Zend_Log_Writer_Stream('/path/to/file.log');
+$log    = new Zend_Log($writer);
+
+// Attach it to the translation instance
+$translate->setOptions(array(
+    'log'             => $log,
+    'logUntranslated' => true));
+
+$translate->translate('unknown string');
+]]></programlisting>
+        </example>
+
+        <para>
+            Now you will have a new notice in the log: <code>Untranslated message within 'de': unknown string</code>.
+        </para>
+
+        <note>
+            <para>
+                You should note that any translation which can not be found will be logged. This means
+                all translations when a user requests a language which is not supported. Also every request
+                for a message which can not be translated will be logged. Be aware, that 100 people
+                requesting the same translation, will result 100 logged notices.
+            </para>
+        </note>
+
+        <para>
+            This feature can not only be used to log messages but also to attach this untranslated messages
+            into an empty translation file. To do so you will have to write your own log writer which
+            writes the format you want to have and strips the prepending "Untranslated message".
+        </para>
+
+        <para>
+            You can also set the '<code>logMessage</code>' option when you want to have your own log message.
+            Use the '<code>%message%</code>' token for placing the messageId within your log message, and the
+            '<code>%locale%</code>' token for the requested locale. See the following example for a self
+            defined log message:
+        </para>
+
+        <example id="zend.translate.additional.logging.example2">
+            <title>Self defined log messages</title>
+            <programlisting role="php"><![CDATA[
+$translate = new Zend_Translate('gettext', $path, 'de');
+
+// Create a log instance
+$writer = new Zend_Log_Writer_Stream('/path/to/file.log');
+$log    = new Zend_Log($writer);
+
+// Attach it to the translation instance
+$translate->setOptions(array(
+    'log'             => $log,
+    'logMessage'      => "Missing '%message%' within locale '%locale%'",
+    'logUntranslated' => true));
+
+$translate->translate('unknown string');
+]]></programlisting>
+        </example>
+
+    </sect2>
+
+    <sect2 id="zend.translate.additional.sourcedata">
+
+        <title>Accessing source data</title>
+
+        <para>
+            Sometimes it is useful to have access to the translation source data. Therefor
+            the following two functions are provided.
+        </para>
+
+        <para>
+            The <code>getMessageIds($locale = null)</code> method returns all known message IDs as array.
+        </para>
+
+        <para>
+            The <code>getMessages($locale = null)</code> method returns the complete translation source as
+            an array. The message ID is used as key and the translation data as value.
+        </para>
+
+        <para>
+            Both methods accept an optional parameter <code>$locale</code> which, if set, returns the
+            translation data for the specified language. If this parameter is not given, the actual set
+            language will be used. Keep in mind that normally all translations should be available in all
+            languages. Which means that in a normal situation you will not have to set this parameter.
+        </para>
+
+        <para>
+            Additionally the <code>getMessages()</code> method can be used to return the complete
+            translation dictionary using the pseudo-locale 'all'. This will return all available
+            translation data for each added locale.
+        </para>
+
+        <note>
+            <para>
+                Attention: the returned array can be <emphasis>very big</emphasis>,
+                depending on the number of added locales and the amount of translation data.
+            </para>
+        </note>
+
+        <example id="zend.translate.additional.sourcedata.example">
+            <title>Handling languages with adapters</title>
+            <programlisting role="php"><![CDATA[
+// returns all known message IDs
+$messageIds = $translate->getMessageIds();
+print_r($messageIds);
+
+// or just for the specified language
+$messageIds = $translate->getMessageIds('en_US');
+print_r($messageIds);
+
+// returns all the complete translation data
+$source = $translate->getMessages();
+print_r($source);
+]]></programlisting>
+        </example>
+
+    </sect2>
+
+</sect1>
+<!--
+vim:se ts=4 sw=4 et:
+-->

+ 292 - 0
documentation/manual/en/module_specs/Zend_Translate-Plurals.xml

@@ -0,0 +1,292 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Reviewed: no -->
+<sect1 id="zend.translate.plurals">
+
+    <title>Plural notations for Translation</title>
+
+    <para>
+        As of Zend Framework 1.9, <classname>Zend_Translate</classname> is able to provide plural
+        support. Professional translation will always have the need to use plurals as they are
+        native in almost all languages.
+    </para>
+
+    <para>
+        So what are plurals? Generally spoken plurals are words which take into account numeric
+        meanings. But as you may imaging each language has it's own definition of plurals.
+        English, for example, supports one plural. We have a singular definition, for example
+        "car", which means implicit one car, and we have the plural definition, "cars" which could
+        mean more than one car but also zero cars. Other languages like russian or polish have
+        more plurals and also the rules for plurals are different.
+    </para>
+
+    <para>
+        When you want to use plurals with <classname>Zend_Translate</classname> you must not need
+        to know how the plurals are defined, only the translator must know as he does the
+        translation. The only information you need to have is the language.
+    </para>
+
+    <para>
+        There are two way for using plurals... the traditional one, which means that you use a own
+        method, and a modern one, which allows you to do plural translations with the same method
+        as normal translations.
+    </para>
+
+    <sect2 id="zend.translate.plurals.traditional">
+
+        <title>Traditional plural translations</title>
+
+        <para>
+            People who worked with gettext in past will be more common with traditional plural
+            translations. There is a own <methodname>plural()</methodname> method which can be
+            used for plural translations.
+        </para>
+
+        <example id="zend.translate.plurals.traditional.example1">
+
+            <title>Example of traditional plural translations</title>
+
+            <para>
+                The <methodname>plural()</methodname> method accepts 4 parameters. The first
+                parameter is the singular messageId, the second is the plural messageId and the
+                third is the number or amount.
+            </para>
+
+            <para>
+                The number will be used to detect the plural which has to be returned. A optional
+                forth parameter can be used to give a locale which will be used to return the
+                translation.
+            </para>
+
+            <programlisting role="php"><![CDATA[
+$translate = new Zend_Translate('gettext', '/path/to/german.mo', 'de');
+$translate->plural('Car', 'Cars', $number);
+]]></programlisting>
+
+        </example>
+
+    </sect2>
+
+    <sect2 id="zend.translate.plurals.modern">
+
+        <title>Modern plural translations</title>
+
+        <para>
+            As traditional plural translations are restricted to source code using english plurals
+            we added a new way for plural translations. It allows to use the same
+            <methodname>translate()</methodname> for standard and for plural translations.
+        </para>
+
+        <para>
+            To use plural translations with <methodname>translate()</methodname> you need to give
+            an array as messageId instead of an string. This array must have the original plural
+            messageId's, then the amount and at last an optional locale when your given messageId's
+            are not in english notation.
+        </para>
+
+        <example id="zend.translate.plurals.modern.example1">
+
+            <title>Example of modern plural translations</title>
+
+            <para>
+                When we want to translate the same plural definitions like in the previous our
+                example would have to be defined like below.
+            </para>
+
+            <programlisting role="php"><![CDATA[
+$translate = new Zend_Translate('gettext', '/path/to/german.mo', 'de');
+$translate->translate(array('Car', 'Cars', $number));
+]]></programlisting>
+
+        </example>
+
+        <para>
+            Using modern plural translations it is also possible to use any language as source
+            for messageId's.
+        </para>
+
+        <example id="zend.translate.plurals.modern.example2">
+
+            <title>Example of modern plural translations using a different source language</title>
+
+            <para>
+                Let's expect we want to use russian and let's also expect that the given
+                messageId's are russian and not english.
+            </para>
+
+            <programlisting role="php"><![CDATA[
+$translate = new Zend_Translate('gettext', '/path/to/german.mo', 'de');
+$translate->translate(array('Car', 'Cars first plural', 'Cars second plural', $number, 'ru'));
+]]></programlisting>
+
+        </example>
+
+        <para>
+            As you can see you can give more than just the one english plural. But you must give
+            the source language in this case so <classname>Zend_Translate</classname> knows which
+            plural rules it has to apply.
+        </para>
+
+        <para>
+            When you omit the plural language then english will be used per default and any
+            additional plural definition will be ignored.
+        </para>
+
+    </sect2>
+
+    <sect2 id="zend.translate.plurals.source">
+
+        <title>Plural source files</title>
+
+        <para>
+            Not all source formats support plural forms. Look into this list for details:
+        </para>
+
+        <table id="zend.translate.plurals.source.supportedadapters">
+            <title>Plural support</title>
+            <tgroup cols="4">
+                <thead>
+                    <row>
+                        <entry>Adapter</entry>
+                        <entry>Plurals supported</entry>
+                    </row>
+                </thead>
+                <tbody>
+                    <row>
+                        <entry>Array</entry>
+                        <entry><emphasis>yes</emphasis></entry>
+                    </row>
+                    <row>
+                        <entry>Csv</entry>
+                        <entry><emphasis>yes</emphasis></entry>
+                    </row>
+                    <row>
+                        <entry>Gettext</entry>
+                        <entry><emphasis>yes</emphasis></entry>
+                    </row>
+                    <row>
+                        <entry>Ini</entry>
+                        <entry><emphasis>no</emphasis></entry>
+                    </row>
+                    <row>
+                        <entry>Qt</entry>
+                        <entry><emphasis>no</emphasis></entry>
+                    </row>
+                    <row>
+                        <entry>Tbx</entry>
+                        <entry><emphasis>no</emphasis></entry>
+                    </row>
+                    <row>
+                        <entry>Tmx</entry>
+                        <entry><emphasis>no</emphasis></entry>
+                    </row>
+                    <row>
+                        <entry>Xliff</entry>
+                        <entry><emphasis>no</emphasis></entry>
+                    </row>
+                    <row>
+                        <entry>XmlTm</entry>
+                        <entry><emphasis>no</emphasis></entry>
+                    </row>
+                </tbody>
+            </tgroup>
+        </table>
+
+        <para>
+            Below you can find examples of plural defined source files.
+        </para>
+
+        <sect3 id="zend.translate.plurals.source.array">
+
+            <title>Array source with plural definitions</title>
+
+            <para>
+                An array with plural definitions has to look like the following example.
+            </para>
+
+            <programlisting role="php"><![CDATA[
+array(
+    'plural_0' => array(
+        'plural_0 (ru)',
+        'plural_1 (ru)',
+        'plural_2 (ru)',
+        'plural_3 (ru)'
+    ),
+    'plural_1' => ''
+);
+]]></programlisting>
+
+            <para>
+                In the above example <code>plural_0</code> and <code>plural_1</code> are the
+                plural definitions from the source code. And the array at <code>plural_0</code>
+                has all translated plural forms available. Take a look at the following example
+                with real content and translation from english source to german.
+            </para>
+
+            <programlisting role="php"><![CDATA[
+array(
+    'Car' => array(
+        'Auto',
+        'Autos'
+    ),
+    'Cars' => ''
+);
+]]></programlisting>
+
+            <para>
+                When your translated language supports more plural forms then simply add them to
+                the array below the first plural form. When your source language suppors more
+                plural forms, than simply add a new empty translation.
+            </para>
+
+        </sect3>
+
+        <sect3 id="zend.translate.plurals.source.csv">
+
+            <title>Csv source with plural definitions</title>
+
+            <para>
+                A csv file with plural definitions has to look like the following example.
+            </para>
+
+            <programlisting role="php"><![CDATA[
+"plural_0";"plural_0 (ru)";"plural_1 (ru)";"plural_2 (ru)";"plural_3 (ru)"
+"plural_1";
+]]></programlisting>
+
+            <para>
+                All translated plural forms have to be added after the first plural of the source
+                language. And all further plural forms of the source language have to be added
+                below but without translation. Note that you must add a delimiter to empty
+                source plurals.
+            </para>
+
+        </sect3>
+
+        <sect3 id="zend.translate.plurals.source.gettext">
+
+            <title>Gettext source with plural definitions</title>
+
+            <para>
+                Gettext sources support plural forms out of the box. There is no need for adoption
+                as the <filename>*.mo</filename> file will contain all necessary data.
+            </para>
+
+            <note>
+
+                <para>
+                    Note that gettext does not support the usage of source languages which are not
+                    using english plural forms. When you plan to use a source language which
+                    supports other plural forms like russian for example, then you can not use
+                    gettext sources.
+                </para>
+
+            </note>
+
+        </sect3>
+
+    </sect2>
+
+</sect1>
+<!--
+vim:se ts=4 sw=4 et:
+-->

+ 19 - 18
documentation/manual/en/module_specs/Zend_Translate-Using.xml

@@ -165,7 +165,7 @@ print $translate->_(2) . "\n";
                     Single structured source
                 </para>
 
-                <programlisting><![CDATA[
+                <programlisting language="txt"><![CDATA[
 /application/
 /languages/
 /languages/lang.en
@@ -183,7 +183,7 @@ print $translate->_(2) . "\n";
                     Language structured source
                 </para>
 
-                <programlisting><![CDATA[
+                <programlisting language="txt"><![CDATA[
 /application/
 /languages/
 /languages/en/
@@ -206,7 +206,7 @@ print $translate->_(2) . "\n";
                     Application structured source
                 </para>
 
-                <programlisting><![CDATA[
+                <programlisting language="txt"><![CDATA[
 /application/
 /application/languages/
 /application/languages/first.en
@@ -231,7 +231,7 @@ print $translate->_(2) . "\n";
                     Gettext structured source
                 </para>
 
-                <programlisting><![CDATA[
+                <programlisting language="txt"><![CDATA[
 /application/
 /languages/
 /languages/de/
@@ -260,7 +260,7 @@ print $translate->_(2) . "\n";
                    File structured source
                 </para>
 
-                <programlisting><![CDATA[
+                <programlisting language="txt"><![CDATA[
 /application/
 /application/models/
 /application/models/MyModel.php
@@ -463,7 +463,7 @@ $translate = new Zend_Translate('tmx', 'path/to/mytranslation.tmx', 'en');
 
         <para>
             If you want to have only specified languages from the source translated
-            you can set the option '<code>defined_language</code>' to <code>true</code>.
+            you can set the option '<code>defined_language</code>' to <constant>TRUE</constant>.
             With this option you can add the wished languages explicitly with
             <code>addLanguage()</code>. The default value for this option is to add all
             languages.
@@ -482,7 +482,7 @@ $translate = new Zend_Translate('tmx', 'path/to/mytranslation.tmx', 'en');
 
         <example id="zend.translate.using.source.csv.example">
             <title>Example CSV file</title>
-            <programlisting><![CDATA[
+            <programlisting language="txt"><![CDATA[
 #Example csv file
 message1;Nachricht1
 message2;Nachricht2
@@ -520,7 +520,7 @@ $translate->addTranslation('path/to/other.csv', 'fr');
 
         <example id="zend.translate.using.source.csv.example2">
             <title>Second CSV file example</title>
-            <programlisting><![CDATA[
+            <programlisting language="txt"><![CDATA[
 # Example CSV file
 "message,1",Nachricht1
 message2,"Nachricht,2"
@@ -552,7 +552,7 @@ $translate->addTranslation('/path/to/other.csv', 'fr');
 
         <example id="zend.translate.using.source.ini.example">
             <title>Example INI file</title>
-            <programlisting><![CDATA[
+            <programlisting language="txt"><![CDATA[
 [Test]
 ;TestPage Comment
 Message_1="Nachricht 1 (de)"
@@ -570,9 +570,9 @@ $translate->addTranslation('/path/to/other.ini', 'it');
             INI files have several restrictions. If a value in the ini file contains any
             non-alphanumeric characters it needs to be enclosed in double-quotes (<code>"</code>).
             There are also reserved words which must not be used as keys for ini files.
-            These include: <code>null</code>, <code>yes</code>, <code>no</code>, <code>true</code>,
-            and <code>false</code>. Values <code>null</code>, <code>no</code> and <code>false</code> results
-            in <code>""</code>, <code>yes</code> and <code>true</code> results in <code>1</code>. Characters <code>{}|&amp;~![()"</code> must not be used anywhere
+            These include: <constant>NULL</constant>, <code>yes</code>, <code>no</code>, <constant>TRUE</constant>,
+            and <constant>FALSE</constant>. Values <constant>NULL</constant>, <code>no</code> and <constant>FALSE</constant> results
+            in <code>""</code>, <code>yes</code> and <constant>TRUE</constant> results in <code>1</code>. Characters <code>{}|&amp;~![()"</code> must not be used anywhere
             in the key and have a special meaning in the value. Do not use them as it will
             produce unexpected behaviour.
         </para>
@@ -764,7 +764,7 @@ $translate->addTranslation('/path/to/new.csv', 'fr', $options);
 
         <para>
             The <code>isAvailable()</code> method checks if a given language is already available. It returns
-            <code>true</code> if data for the given language exist.
+            <constant>TRUE</constant> if data for the given language exist.
         </para>
 
         <para>
@@ -1045,7 +1045,7 @@ $translate = new Zend_Translate(
                     if you have only one file per language.
                 </para>
 
-                <programlisting><![CDATA[
+                <programlisting language="txt"><![CDATA[
 /languages/
 /languages/en.mo
 /languages/de.mo
@@ -1064,7 +1064,7 @@ $translate = new Zend_Translate(
                     originally had.
                 </para>
 
-                <programlisting><![CDATA[
+                <programlisting language="txt"><![CDATA[
 /languages/
 /languages/view.en
 /languages/view.de
@@ -1084,7 +1084,7 @@ $translate = new Zend_Translate(
                     a hyphen '-'.
                 </para>
 
-                <programlisting><![CDATA[
+                <programlisting language="txt"><![CDATA[
 /languages/
 /languages/view_en.mo -> detects english
 /languages/view_de.mo -> detects german
@@ -1096,7 +1096,7 @@ $translate = new Zend_Translate(
                     example for details.
                 </para>
 
-                <programlisting><![CDATA[
+                <programlisting language="txt"><![CDATA[
 /languages/
 /languages/view_en_de.mo -> detects english
 /languages/view_en_es.mo -> detects english and overwrites the first file
@@ -1109,7 +1109,7 @@ $translate = new Zend_Translate(
                     example for details.
                 </para>
 
-                <programlisting><![CDATA[
+                <programlisting language="txt"><![CDATA[
 /languages/
 /languages/view_en-it.mo -> detects english because '_' will be used before '-'
 /languages/view-en_it.mo -> detects italian because '_' will be used before '-'
@@ -1306,6 +1306,7 @@ print_r($source);
 
     </sect2>
 
+>>>>>>> .r15606
 </sect1>
 <!--
 vim:se ts=4 sw=4 et: