From 0723f409ab0a389609187fe8c1336147ccab8262 Mon Sep 17 00:00:00 2001 From: Carsten Brandt Date: Wed, 10 Sep 2014 19:13:06 +0200 Subject: [PATCH] finished the first structure of the guide on formatting --- docs/guide/output-data-widgets.md | 26 +-- docs/guide/output-formatter.md | 323 +++++++----------------------- framework/i18n/Formatter.php | 2 +- 3 files changed, 73 insertions(+), 278 deletions(-) diff --git a/docs/guide/output-data-widgets.md b/docs/guide/output-data-widgets.md index af82975e838..525116d8cc3 100644 --- a/docs/guide/output-data-widgets.md +++ b/docs/guide/output-data-widgets.md @@ -162,30 +162,8 @@ In the above `text` corresponds to [[\yii\i18n\Formatter::asText()]]. The value argument. In the second column definition `date` corresponds to [[\yii\i18n\Formatter::asDate()]]. The value of the column is, again, passed as the first argument while 'Y-m-d' is used as the second argument value. -Here's the bundled formatters list: - -- [[\yii\base\Formatter::asRaw()|raw]] - the value is outputted as is. -- [[\yii\base\Formatter::asText()|text]] - the value is HTML-encoded. This format is used by default. -- [[\yii\base\Formatter::asNtext()|ntext]] - the value is formatted as an HTML-encoded plain text with newlines converted - into line breaks. -- [[\yii\base\Formatter::asParagraphs()|paragraphs]] - the value is formatted as HTML-encoded text paragraphs wrapped - into `

` tags. -- [[\yii\base\Formatter::asHtml()|html]] - the value is purified using [[HtmlPurifier]] to avoid XSS attacks. You can - pass additional options such as `['html', ['Attr.AllowedFrameTargets' => ['_blank']]]`. -- [[\yii\base\Formatter::asEmail()|email]] - the value is formatted as a mailto link. -- [[\yii\base\Formatter::asImage()|image]] - the value is formatted as an image tag. -- [[\yii\base\Formatter::asUrl()|url]] - the value is formatted as a hyperlink. -- [[\yii\base\Formatter::asBoolean()|boolean]] - the value is formatted as a boolean. You can set what's rendered for - true and false values by calling `Yii::$app->formatter->booleanFormat = ['No', 'Yes'];` before outputting GridView. -- [[\yii\base\Formatter::asDate()|date]] - the value is formatted as date. -- [[\yii\base\Formatter::asTime()|time]] - the value is formatted as time. -- [[\yii\base\Formatter::asDatetime()|datetime]] - the value is formatted as datetime. -- [[\yii\base\Formatter::asInteger()|integer]] - the value is formatted as an integer. -- [[\yii\base\Formatter::asDouble()|double]] - the value is formatted as a double number. -- [[\yii\base\Formatter::asNumber()|number]] - the value is formatted as a number with decimal and thousand separators. -- [[\yii\base\Formatter::asSize()|size]] - the value that is a number of bytes is formatted as a human readable size. -- [[\yii\base\Formatter::asRelativeTime()|relativeTime]] - the value is formatted as the time interval between a date - and now in human readable form. +For a list of available formatters see the [section about Data Formatting](output-formatter.md). + #### Action column diff --git a/docs/guide/output-formatter.md b/docs/guide/output-formatter.md index 147dc8d7543..5f1fa8b436d 100644 --- a/docs/guide/output-formatter.md +++ b/docs/guide/output-formatter.md @@ -14,6 +14,8 @@ The formatter can be used in two different ways. echo Yii::$app->formatter->asPercent(0.125, 2); // output: 12.50% echo Yii::$app->formatter->asEmail('cebe@example.com'); // output: cebe@example.com echo Yii::$app->formatter->asBoolean(true); // output: Yes + // it also handles display of null values: + echo Yii::$app->formatter->asDate(null); // output: (Not set) ``` 2. Using the [[yii\i18n\Formatter::format()|format()]] method using the format name. @@ -29,280 +31,95 @@ The formatter can be used in two different ways. All output of the formatter is localized when the [PHP intl extension](http://php.net/manual/en/book.intl.php) is installed. You can configure the [[yii\i18n\Formatter::locale|locale]] property of the formatter for this. If not configured, the -application [[language]] is used as the locale. See the [Section on internationaization](tutorial-i18n.md) for more details. +application [[yii\base\Application::language|language]] is used as the locale. See the [Section on internationaization](tutorial-i18n.md) for more details. +The Formatter will then choose the correct format for dates and number according to the locale including names of month and +week days translated to the current language. Date formats are also affected by the [[yii\i18n\Formatter::timeZone|timeZone]] +which will also be taken [[yii\base\Application::timeZone|from the application]] by default. - * > Note that formatting may differ between different versions of the ICU library compiled with PHP. - * > You - * - - -Formatter is a helper component to format machine readable data of type date, time, different number types -in user readable formats. Most of this types are in countries differently formatted (eg. date: US -> '10/31/2014, -or DE -> '31.10.2014' or ISO -> '2014-10-31'). Same with decimals and currency values (eg. currency: US-> '$ 13,250.22' or -de-DE -> '13.250,22 �' or de-CH ->'CHF 13'250.22') - - -Formatter uses the php extension "intl" if the extension is loaded. "Intl" uses [ICU standard](http://site.icu-project.org/) driven -by IBM. "intl" internally knows all formats of all countries and it translates month or day names into the corrcect language. -Unfortunately ICU don't use same format patterns like php (eg. ICU: 'yyyy-mm-dd' php: 'Y-m-d' or icu: 'yy-m-d' php: 'y-n-j'). -Therefore formatter class has built in a pattern conversions from php to icu or icu to php. Formatter communicates in their interface -functions per standard with php patterns, but it's also possible to communicate with icu patterns. (compare patterns see [PDF](http://www.guggach.com/tl_files/yii2/Difference%20of%20Date%20formats%20%20used%20in%20Yii2.pdf)) - -If "intl" isn't loaded formatter works also in the same way. Even the named date, time or datetime formats from icu "short", "medium", "long" -and "full" are supported. Without a separate localized format definition US formats are used. Formatter provides a possibility to enter -localized format patterns in an array (class formatDefs). Formatter uses this definitions but can't translate month or day names into the -correct language. - -If the application should support localized outputs "intl" extension should be enabled in php.ini. If Apache (xampp on windows only) doesn't -start correctly then you must install a library of Microsoft ([Visual C++ Redistributable](http://www.microsoft.com/de-de/download/details.aspx?id=30679)) - -Installation / Configuration ----------------------------- -Formatter class must be registered in Yii config (eg. app/config/web.php) in section 'components'. The class must be specified. All other parameters are -optional. The following example shows all parameters and explain their default values. In most cases default values are ideal. +For example the date format call will output different results for different locales: ```php -'components' => [ - 'formatter' => [ - 'class' => 'guggach\helpers\Formatter', - // 'dateFormat' => 'medium', // default: 'medium' - // 'timeFormat' => 'medium', // default: 'medium' - // 'datetimeFormat' => 'medium' // default: 'medium' - // 'dbFormat' => ['date' => 'Y-m-d','time' => 'H:i:s', 'dbtimeshort'=>'H:i' ,'datetime' => 'Y-m-d H:i:s', - 'dbdatetimeshort' => 'Y-m-d H:i'] - // 'local' => 'de-CH' // default: yii::$app->locale - // 'timezone' => 'Europe/Berlin' // default: yii::$app->timezone - // 'nullDisplay => '(not set)' // default '(not set)' translated with yii::t - // 'booleanFormat' => ['No', 'Yes'] // default: ['No', 'Yes'] translated with yii::t - // 'numberFormatOptions' => [] // see intl NumberFormatter - // 'numberTextFormatOptions' => [] // see intl NumberFormatter - // 'decimalSeparator' => '.' // default ICU locale definition or FormatDefs class - // 'thousandSeparator' => ',' // default ICU locale definition or FormatDefs class - // 'currencyCode' => 'USD' // default ICU locale definition or FormatDefs class - // 'RoundingIncrement' => 0.01 // default to number of decimals, currency = 0.01 (except Switzerland 0.05) - // 'sizeFormat' => [] // default ['base' = 1024 , 'decimals' = 2, 'decimalSeparator' = null] - ]; +Yii::$app->formatter->locale = 'en-US'; +echo Yii::$app->formatter->asDate('2014-01-01'); // output: January 1, 2014 +Yii::$app->formatter->locale = 'de-DE'; +echo Yii::$app->formatter->asDate('2014-01-01'); // output: 1. Januar 2014 +Yii::$app->formatter->locale = 'ru-RU'; +echo Yii::$app->formatter->asDate('2014-01-01'); // output: 1 января 2014 г. ``` -Details for each parameter are described in formatter.php. - -Using formatter ---------------- -Formatter is a general component which is registered in `yii::$app->formatter`. Mostly used funtions are `yii::$app->formatter->format()` -or `yii::$app->formatter->unformat()`. - -Usage in Code, example: - - - $formattedValueString = yii::$app->formatter->format($value, ['date' , 'd-m-y' , 'php']); - - $value = yii::$app->formatter->unformat($formattedValueString, ['currency']); - - -Format and unformat function has minimal two parameter like - -`(un)format( mixed $value , [ 'format as' , 'optional 1', 'optional 2' ... ])` - -1. $value (must): machine readable date, time, datetime or number which hast to be formatted. -2. 'format as' (must): defines what type the value is and what kind of format is expected. -3. 'Option n': The number of paramters and the content is dependant of 'format as'. Details see in further chapters. - -In following chapters all formatters are described in detail with input parameters. - - -###Format or unformat as 'date' or 'time or 'datetime - -`format(date (mixed), ['date'/'time'/'datetime' , 'target format pattern', 'input format pattern' , 'format type'])` - -####Input: -1. date mixed (must): -It can be a Unix timestamp, DateTime object or a date string. A string must be in ISO format ('2014-10-05') or in local -date format (de-DE: '05.10.2014'). If another format is given the 'input format pattern' must be specified (eg. US: 'M/d/Y') -2. 'date'/'time'/'datetime' (must): -A timestamp (DateTime object) can be formatted in a date (eg. '2014-10-05') or a time (eg. 15:20:30) or in a -datetime (eg. '2014-10-05 15:20:30'). This parameter specifies which of these three formats should be done. -3. 'target format pattern' (optinal): -Formatter has four predefined format patterns: `short` ('y-n-j' = 14-10-25), `medium`('Y-m-d' = 2014-10-25), `long` ('F j, Y' = October -25, 2014) or 'full' ('l, F j, Y' = Saturday, October 25, 2014). An individual format can be defined by a pattern string like 'd. F Y' ( 25. October 2014). -The individual pattern string is per default in 'php' syntax. Alternatively ICU pattern (dd. MMMM yyyy) could be used. (see format type) -4. 'input format pattern' (optional): -If input date is a string formatter convert into a DateTime object internally. Formatter recognize ISO format (2014-10-25) or locale format. -All other formats will produce a false result unless the input format is defined in this parameter. Default format pattern is php. -5. 'format type' (optional): -Per default formatter communicates with 'php' format patterns independent if ICU is used or not. This makes format handling in Yii easier because -a developer is concentrating to one format all over the application. Nevertheless ICU patterns can be used if this parameter is 'icu'. - -####Output: -Formatted string like '25th October 2014'. - - - -`unformat(date (string), ['date'/'time'/'datetime', 'target format', 'input format pattern', 'format type'])` - -####Input: -1. date as string: -Formatted date as string. The string must be in ISO format ('2014-10-05') or in local -date format (de-DE: '05.10.2014'). If another format is given the 'input format pattern' must be specified (eg. US: 'M/d/Y'). -2. 'date'/'time'/'datetime' (must): -Defines if input is a date or a time or a datetime string. -3. 'target format' (optional): -Valid values are `'db'`or `'timestamp'`. Default is 'db' because a user readable date string must be stored in a database. Databases mostly -accept ISO format ('2014-10-25') only. If format is different the database format can be configured in variable `dbFormat` (array). -4. 'input format pattern' (optional): -see format date function -5. 'format type' (optional): -see format date function - -###Format as Timestamp - -`format ('date'/'time'/'datetime' (string), ['timestamp', 'input format pattern'])` +> Note that formatting may differ between different versions of the ICU library compiled with PHP and also based on the fact whether the +> [PHP intl extension](http://php.net/manual/en/book.intl.php) is installed or not. So to ensure your website works with the same output +> in all environments it is recommended to install the PHP intl extension in all environments and verify that the version of the ICU library +> is the same. -####Input: -Parameter see 'format date'. +Configuring the format +---------------------- -####Output: +The default format of the Formatter class can be adjusted using the properties of the formatter class. +You can adjust these values application wide by configuring the `formatter` component in your [application config](concept-configurations.md#application-configurations) +an example configuration is shown in the following. +For more details about certain properties check out the [[yii\i18n\Formatter|API documentation of the Formatter class]]. -Long integer (64bit or float) with Unix Timestamp in seconds from 01/01/1970. - - -###Format or unformat as Integer - -`format(value (mixed), ['integer' , 'thousandSeparator'])` - -`unformat(value (string), 'integer')` - -####Input: -1. value (integer, float, numeric string) (must): -In format function a numeric string or a float or an integer is necessary. A float with decimals will be mathematically rounded to an integer. -The unformat function needs a string which can have thousand separators but it must be numeric. -2. 'integer' (string)(must): -This is the name of formatting function which is used. -3. 'thousandSeparator' (boolean) (optional): -Valid values are `true`or `false`. Default is `true`. If value is true the output is formatted with thousand separator concerning the locale -definition or the value of the variable 'thousandSeparator'. - -####Output: -Formatted string like '23,456,698'. - -###Format or unformat as Double, Number, Decimal -Double, Number, Decimal are all synonyms for floating numbers with decimals. - -`format(value (mixed), ['double', decimals (int) , roundIncrement (float), grouping (boolean)` - -`unformat(value (string), 'double')` - -####Input: -1. value (float, numeric string) (must): -In format function a numeric string or a float is necessary. A float with decimals will be mathematically rounded to the number of decimals. -The unformat function needs a string which can have thousand separators but it must be numeric. -2. 'double' (string) (must): -This is the name of the formatting function. As synonym 'decimals' and 'number' could be used. -3. decimals (integer) (optional): -Number of decimals after comma. Per default 2 is set. If the number of decimals is less than 6 zeros are filled until number of decimals -(eg. decimals = 4 -> 3.42 -> 3.4200). -4. RoundIncrement (float) (optinal): -If roundIncrement isn't set the float will be rounded to last requested decimal with mathematical rule (eg. decimals = 3 -> 3.45662 --> 3.457). -If roundIncrement is set to '0.01' float will be rounded to this value (eg. decimals = 3 -> 3.45662 -> 3.46000). -5. Grouping (boolean) (optional): -If value is true the float will be formatted with thousand separator otherwise not. Default is true. - -####Output: -Formatted string like '3,456,698.65' - -###Format or unformat as currency - -`format(value (mixed), ['currency', 'currency code' (string) , roundIncrement (float), grouping (boolean)` - -`unformat(value (string), 'currency')` - -###Input: -1. value (float, numeric string) (must): -In format function a numeric string or a float is necessary. The currency amount with decimals will be mathematically rounded to two decimals. -The unformat function needs a string which can have thousand separators but it must be numeric. -2. 'currency' (string) (must): -This is the name of the formatting function. -3. 'currency code' (string) (optional): -Normally currency code is provided by ICU from locale setting. If another currency is needed the code as string can be set here. -4. RoundIncrement (float) (optinal): -If roundIncrement isn't set the float will be rounded to last requested decimal with mathematical rule. -If roundIncrement is set to '0.05' (Switzerland with 5 cents only) float will be rounded to this value (eg. 3.26 -> 3.25 or 3.275 -> 3.30). -5. Grouping (boolean) (optional): -If value is true the float will be formatted with thousand separator otherwise not. Default is true. - -####Output: -Formatted string like '$ 13,256.23' - -###Format or unformat as scientific - -`format(value (mixed), ['scientific', decimals (integer))` - -`unformat(value (string), 'scientific')` - -Scientific formats a float to a scientifc string like '23216' to '2.32166E4'. - -###Format or unformat as percent - -`format(value (mixed), ['percent', decimals (integer) , grouping (boolean)` - -`unformat(value (string), 'percent')` - -###Input: -1. value (float, numeric string) (must): -In format function a numeric string or a float is necessary. Value is a factor like '0.75' -> '75%'. -The unformat function needs a string which can have thousand separators but it must be numeric. It will be converted back to a factor. '75%' -> '0.75' -2. 'percent': -This is the name of the formatting function. -3. decimals (integer) (optional): -Number of decimals. The formatter rounds a float to the number of decimals. -4. Grouping (boolean) (optional): -If value is true the percent value will be formatted with thousand separator otherwise not. Default is true. +```php +'components' => [ + 'formatter' => [ + 'dateFormat' => 'dd.MM.yyyy', + 'decimalSeparator' => ',', + 'thousandSeparator' => ' ', + 'currencyCode' => 'EUR', + ]; +``` -####Output: -Formatted string like '75.05%'. The unformatter produces a float as factor like 0.7505. +Formatting Dates +---------------- -###Further formatters -Formatter has formatting rules for Text, HTML, Email, Boolean etc. +TDB -`format(value (mixed), 'name of formatter')` +See http://site.icu-project.org/ for the format. -Formatters are: -`boolean:` Ouput is a string with 'Yes' or 'No' translated to locale setting. -`email:` Converts an email address to a 'mailto' link. -`html:` Converts a string with html-purifier to avoid XSS attacks. -`image:` Formats a html image tag around a path to image. -`NText:` Formats the value as an HTML-encoded plain text with newlines converted into breaks. -`Paragraphs:` Formats the value as HTML-encoded text paragraphs. Each text paragraph is enclosed within a `

` tag. -`raw:` Formats the value as is without any formatting. Null values are showed as 'not set'. -`size:` Formats a number as byte, kilobyte, megabyte etc. depending on the size of the number. Normally 'Mb' is given unless optional parameter is true. -`text:` Formats the value as an HTML-encoded plain text. -`url:` Formats the value as a hyperlink. If necessary it adds 'https://'. +- [[\yii\i18n\Formatter::asDate()|date]] - the value is formatted as date. +- [[\yii\i18n\Formatter::asTime()|time]] - the value is formatted as time. +- [[\yii\i18n\Formatter::asDatetime()|datetime]] - the value is formatted as datetime. +- [[\yii\i18n\Formatter::asTimestamp()|timestamp]] - the value is formatted as a unix timestamp. +- [[\yii\i18n\Formatter::asRelativeTime()|relativeTime]] - the value is formatted as the time interval between a date + and now in human readable form. -Other functions ---------------- -###getLocale() -Shows the current used locale setting in format like 'de-DE'. +Formatting Numbers +------------------ -###setLocale($locale) -Per default formatter uses locale information from application configuration. If another local definition is requested on the fly this function changes the internal pattern settings, decimal sign and thousand separator to the requested locale. It return this formatter object to enable chaining. +TDB -###getDecimalSeparator() -Shows the current separator for decimal number. +See http://site.icu-project.org/ for the format. -###setDecimalSeparator($sign) -Per default formatter uses the decimal separator sign from ICU concerning locale setting. With setDecimalSeparator the value can be overridden. +- [[\yii\i18n\Formatter::asInteger()|integer]] - the value is formatted as an integer. +- [[\yii\i18n\Formatter::asDecimal()|decimal]] - the value is formatted as a number with decimal and thousand separators. +- [[\yii\i18n\Formatter::asPercent()|percent]] - the value is formatted as a percent number. +- [[\yii\i18n\Formatter::asScientific()|scientific]] - the value is formatted as a number in scientific format. +- [[\yii\i18n\Formatter::asCurrency()|currency]] - the value is formatted as a currency value. +- [[\yii\i18n\Formatter::asSize()|size]] - the value that is a number of bytes is formatted as a human readable size. +- [[\yii\i18n\Formatter::asShortSize()|shortSize]] - the value that is a number of bytes is formatted as a human readable size. -###getThousandSeparator() -Shows the current separator for thousand grouping. -###SetThousandSeparator($sign) -Per default formatter uses the thousand separator sign from ICU concerning locale setting. With setThousandSeparator the value can be overridden. +Other formatters +---------------- -###convertPatternPhpToIcu($pattern, $type) -Converts a php date or time format pattern from PHP syntax to ICU syntax (eg. 'Y-m-d' -> 'yyyy-MM-dd'). If pattern is 'short', 'medium', 'long' or 'full' then the parameter 'type' must be defined like 'date', 'time' or 'datetime'. In this case the function delivers the correct ICU pattern (eg. 'medium' and 'date' -> 'dd-MM-yyyy'. +TDB -###convertPatternIcuToPhp($pattern, $type) -Converts a ICU date or time format pattern from ICU syntax to PHP syntax (eg. 'yyyy-MM-dd' -> 'Y-m-d'). If pattern is 'short', 'medium', 'long' or 'full' then the parameter 'type' must be defined like 'date', 'time' or 'datetime'. In this case the function delivers the correct PHP pattern (eg. 'medium' and 'date' -> 'd-m-Y'. +Here's the bundled formatters list: +- [[\yii\i18n\Formatter::asRaw()|raw]] - the value is outputted as is. +- [[\yii\i18n\Formatter::asText()|text]] - the value is HTML-encoded. This format is used by default. +- [[\yii\i18n\Formatter::asNtext()|ntext]] - the value is formatted as an HTML-encoded plain text with newlines converted + into line breaks. +- [[\yii\i18n\Formatter::asParagraphs()|paragraphs]] - the value is formatted as HTML-encoded text paragraphs wrapped + into `

` tags. +- [[\yii\i18n\Formatter::asHtml()|html]] - the value is purified using [[HtmlPurifier]] to avoid XSS attacks. You can + pass additional options such as `['html', ['Attr.AllowedFrameTargets' => ['_blank']]]`. +- [[\yii\i18n\Formatter::asEmail()|email]] - the value is formatted as a mailto link. +- [[\yii\i18n\Formatter::asImage()|image]] - the value is formatted as an image tag. +- [[\yii\i18n\Formatter::asUrl()|url]] - the value is formatted as a hyperlink. +- [[\yii\i18n\Formatter::asBoolean()|boolean]] - the value is formatted as a boolean. You can set what's rendered for + true and false values by calling `Yii::$app->formatter->booleanFormat = ['No', 'Yes'];` before outputting GridView. diff --git a/framework/i18n/Formatter.php b/framework/i18n/Formatter.php index 13df8bcbca6..2ab5b31ccee 100644 --- a/framework/i18n/Formatter.php +++ b/framework/i18n/Formatter.php @@ -536,7 +536,7 @@ private function formatDateTimeValue($value, $format, $type) } /** - * Normalizes the given datetime value as one that can be taken by various date/time formatting methods. + * Normalizes the given datetime value as a UNIX timestamp that can be taken by various date/time formatting methods. * * @param mixed $value the datetime value to be normalized. * @return float the normalized datetime value (int64)