类文档

Gettext_Translations

💡 云策文档标注

概述

Gettext_Translations 类是 WordPress 中用于处理 gettext 翻译的基类,继承自 Translations 类。它提供了复数形式处理、头部信息解析和设置等功能,支持多语言翻译的实现。

关键要点

  • Gettext_Translations 继承自 Translations 类,是 PO 和 MO 翻译文件处理的基础。
  • 核心方法包括 gettext_select_plural_form 用于选择复数形式,nplurals_and_expression_from_header 解析 Plural-Forms 头部信息。
  • 支持通过 make_plural_form_function 生成复数形式函数,并处理头部信息的设置和解析。
  • 包含已弃用的方法 parenthesize_plural_exression,建议使用 Plural_Forms 类替代。
  • 类属性包括 $_nplurals 和 $_gettext_select_plural_form,用于存储复数形式数量和回调函数。

代码示例

// 示例:使用 Gettext_Translations 解析复数形式头部
$translations = new Gettext_Translations();
$header = 'nplurals=2; plural=n != 1;';
list($nplurals, $expression) = $translations->nplurals_and_expression_from_header($header);
// $nplurals 为 2, $expression 为 'n != 1'

注意事项

  • parenthesize_plural_exression 方法自 WordPress 6.5.0 起已弃用,应使用 Plural_Forms 类处理复数表达式。
  • 复数形式处理依赖于 Plural-Forms 头部信息,需确保翻译文件格式正确。
  • 类中的方法主要用于内部翻译系统,开发者通常通过更高级的 API 进行交互。

📄 原文内容

Gettext_Translations class.

Methods

Name Description
Gettext_Translations::gettext_select_plural_form The gettext implementation of select_plural_form.
Gettext_Translations::make_headers Prepare translation headers.
Gettext_Translations::make_plural_form_function Makes a function, which will return the right translation index, according to the plural forms header.
Gettext_Translations::nplurals_and_expression_from_header Returns the nplurals and plural forms expression from the Plural-Forms header.
Gettext_Translations::parenthesize_plural_exression Adds parentheses to the inner parts of ternary operators in plural expressions, because PHP evaluates ternary operators from left to right — deprecated
Gettext_Translations::set_header Sets translation headers.

Source

class Gettext_Translations extends Translations {

	/**
	 * Number of plural forms.
	 *
	 * @var int
	 *
	 * @since 2.8.0
	 */
	public $_nplurals;

	/**
	 * Callback to retrieve the plural form.
	 *
	 * @var callable
	 *
	 * @since 2.8.0
	 */
	public $_gettext_select_plural_form;

	/**
	 * The gettext implementation of select_plural_form.
	 *
	 * It lives in this class, because there are more than one descendant, which will use it and
	 * they can't share it effectively.
	 *
	 * @since 2.8.0
	 *
	 * @param int $count Plural forms count.
	 * @return int Plural form to use.
	 */
	public function gettext_select_plural_form( $count ) {
		if ( ! isset( $this->_gettext_select_plural_form ) || is_null( $this->_gettext_select_plural_form ) ) {
			list( $nplurals, $expression )     = $this->nplurals_and_expression_from_header( $this->get_header( 'Plural-Forms' ) );
			$this->_nplurals                   = $nplurals;
			$this->_gettext_select_plural_form = $this->make_plural_form_function( $nplurals, $expression );
		}
		return call_user_func( $this->_gettext_select_plural_form, $count );
	}

	/**
	 * Returns the nplurals and plural forms expression from the Plural-Forms header.
	 *
	 * @since 2.8.0
	 *
	 * @param string $header
	 * @return array{0: int, 1: string}
	 */
	public function nplurals_and_expression_from_header( $header ) {
		if ( preg_match( '/^s*npluralss*=s*(d+)s*;s+plurals*=s*(.+)$/', $header, $matches ) ) {
			$nplurals   = (int) $matches[1];
			$expression = trim( $matches[2] );
			return array( $nplurals, $expression );
		} else {
			return array( 2, 'n != 1' );
		}
	}

	/**
	 * Makes a function, which will return the right translation index, according to the
	 * plural forms header.
	 *
	 * @since 2.8.0
	 *
	 * @param int    $nplurals
	 * @param string $expression
	 * @return callable
	 */
	public function make_plural_form_function( $nplurals, $expression ) {
		try {
			$handler = new Plural_Forms( rtrim( $expression, ';' ) );
			return array( $handler, 'get' );
		} catch ( Exception $e ) {
			// Fall back to default plural-form function.
			return $this->make_plural_form_function( 2, 'n != 1' );
		}
	}

	/**
	 * Adds parentheses to the inner parts of ternary operators in
	 * plural expressions, because PHP evaluates ternary operators from left to right
	 *
	 * @since 2.8.0
	 * @deprecated 6.5.0 Use the Plural_Forms class instead.
	 *
	 * @see Plural_Forms
	 *
	 * @param string $expression the expression without parentheses
	 * @return string the expression with parentheses added
	 */
	public function parenthesize_plural_exression( $expression ) {
		$expression .= ';';
		$res         = '';
		$depth       = 0;
		for ( $i = 0; $i < strlen( $expression ); ++$i ) {
			$char = $expression[ $i ];
			switch ( $char ) {
				case '?':
					$res .= ' ? (';
					++$depth;
					break;
				case ':':
					$res .= ') : (';
					break;
				case ';':
					$res  .= str_repeat( ')', $depth ) . ';';
					$depth = 0;
					break;
				default:
					$res .= $char;
			}
		}
		return rtrim( $res, ';' );
	}

	/**
	 * Prepare translation headers.
	 *
	 * @since 2.8.0
	 *
	 * @param string $translation
	 * @return array<string, string> Translation headers
	 */
	public function make_headers( $translation ) {
		$headers = array();
		// Sometimes n's are used instead of real new lines.
		$translation = str_replace( 'n', "n", $translation );
		$lines       = explode( "n", $translation );
		foreach ( $lines as $line ) {
			$parts = explode( ':', $line, 2 );
			if ( ! isset( $parts[1] ) ) {
				continue;
			}
			$headers[ trim( $parts[0] ) ] = trim( $parts[1] );
		}
		return $headers;
	}

	/**
	 * Sets translation headers.
	 *
	 * @since 2.8.0
	 *
	 * @param string $header
	 * @param string $value
	 */
	public function set_header( $header, $value ) {
		parent::set_header( $header, $value );
		if ( 'Plural-Forms' === $header ) {
			list( $nplurals, $expression )     = $this->nplurals_and_expression_from_header( $this->get_header( 'Plural-Forms' ) );
			$this->_nplurals                   = $nplurals;
			$this->_gettext_select_plural_form = $this->make_plural_form_function( $nplurals, $expression );
		}
	}
}

Changelog

Version Description
2.8.0 Introduced.