Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ wp i18n
Create a POT file for a WordPress plugin or theme.

~~~
wp i18n make-pot <source> [<destination>] [--slug=<slug>] [--domain=<domain>] [--merge[=<file>]] [--exclude=<paths>] [--skip-js]
wp i18n make-pot <source> [<destination>] [--slug=<slug>] [--domain=<domain>] [--ignore-domain] [--merge[=<file>]] [--exclude=<paths>] [--skip-js]
~~~

Scans PHP and JavaScript files, as well as theme stylesheets for translatable strings.
Expand All @@ -48,7 +48,10 @@ Scans PHP and JavaScript files, as well as theme stylesheets for translatable st
Plugin or theme slug. Defaults to the source directory's basename.

[--domain=<domain>]
Text domain to look for in the source code. Defaults to the plugin/theme slug.
Text domain to look for in the source code. Defaults to the plugin/theme slug, unless the `--ignore-domain` option is used.

[--ignore-domain]
Ignore the text domain completely and extract strings with any text domain.

[--merge[=<file>]]
Existing POT file file whose content should be merged with the extracted strings.
Expand Down
75 changes: 75 additions & 0 deletions features/makepot.feature
Original file line number Diff line number Diff line change
Expand Up @@ -1222,6 +1222,11 @@ Feature: Generate a POT file of a WordPress plugin
"""

When I run `wp i18n make-pot foo-plugin foo-plugin.pot --domain=bar`
Then STDOUT should be:
"""
Plugin file detected.
Success: POT file successfully generated!
"""
And the foo-plugin.pot file should contain:
"""
msgid "Foo"
Expand Down Expand Up @@ -1254,6 +1259,11 @@ Feature: Generate a POT file of a WordPress plugin
"""

When I run `wp i18n make-pot foo-plugin foo-plugin.pot --skip-js`
Then STDOUT should be:
"""
Plugin file detected.
Success: POT file successfully generated!
"""
And the foo-plugin.pot file should contain:
"""
msgid "Foo Plugin"
Expand All @@ -1262,3 +1272,68 @@ Feature: Generate a POT file of a WordPress plugin
"""
msgid "Hello World"
"""

Scenario: Extract all strings regardless of text domain
Given an empty foo-plugin directory
And a foo-plugin/foo-plugin.php file:
"""
<?php
/**
* Plugin Name: Foo Plugin
* Plugin URI: https://example.com
* Description:
* Version: 0.1.0
* Author:
* Author URI:
* License: GPL-2.0+
* License URI: http://www.gnu.org/licenses/gpl-2.0.txt
* Text Domain: foo-plugin
* Domain Path: /languages
*/

__( 'Hello World', 'foo-plugin' );

__( 'Foo', 'bar' );

__( 'bar' );
"""
And a foo-plugin/foo-plugin.js file:
"""
__( '__', 'foo-plugin' );

__( 'wrong-domain', 'wrong-domain' );

__( 'Hello JS' );
"""

When I run `wp i18n make-pot foo-plugin foo-plugin.pot --domain=bar --ignore-domain`
Then STDOUT should be:
"""
Plugin file detected.
Success: POT file successfully generated!
"""
And STDERR should be empty
And the foo-plugin.pot file should contain:
"""
msgid "Hello World"
"""
And the foo-plugin.pot file should contain:
"""
msgid "Foo"
"""
And the foo-plugin.pot file should contain:
"""
msgid "bar"
"""
And the foo-plugin.pot file should contain:
"""
msgid "__"
"""
And the foo-plugin.pot file should contain:
"""
msgid "wrong-domain"
"""
And the foo-plugin.pot file should contain:
"""
msgid "Hello JS"
"""
30 changes: 7 additions & 23 deletions src/JsFunctionsScanner.php
Original file line number Diff line number Diff line change
Expand Up @@ -84,8 +84,8 @@ public function saveGettextFunctions( Translations $translations, array $options
$all_comments[] = $comment;
}

$domain = $context = $original = $plural = null;
$args = [];
$context = $plural = null;
$args = [];

/** @var Node\Node $argument */
foreach ( $node->getArguments() as $argument ) {
Expand All @@ -106,39 +106,23 @@ public function saveGettextFunctions( Translations $translations, array $options
switch ( $functions[ $callee->getName() ] ) {
case 'text_domain':
case 'gettext':
if ( ! isset( $args[1] ) ) {
break;
}

list( $original, $domain ) = $args;
list( $original, $domain ) = array_pad( $args, 2, null );
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, padding with null to avoid PHP errors when you're short on arguments. Nice one!

break;

case 'text_context_domain':
if ( ! isset( $args[2] ) ) {
break;
}

list( $original, $context, $domain ) = $args;
list( $original, $context, $domain ) = array_pad( $args, 3, null );
break;

case 'single_plural_number_domain':
if ( ! isset( $args[3] ) ) {
break;
}

list( $original, $plural, $number, $domain ) = $args;
list( $original, $plural, $number, $domain ) = array_pad( $args, 4, null );
break;

case 'single_plural_number_context_domain':
if ( ! isset( $args[4] ) ) {
break;
}

list( $original, $plural, $number, $context, $domain ) = $args;
list( $original, $plural, $number, $context, $domain ) = array_pad( $args, 5, null );
break;
}

if ( (string) $original !== '' && ( $domain === null || $domain === $translations->getDomain() ) ) {
if ( (string) $original !== '' && ( $domain === $translations->getDomain() || null === $translations->getDomain() ) ) {
$translation = $translations->insert( $context, $original, $plural );
$translation->addReference( $file, $node->getLocation()->getStart()->getLine() );

Expand Down
26 changes: 20 additions & 6 deletions src/MakePotCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,11 @@ class MakePotCommand extends WP_CLI_Command {
*/
protected $skip_js = false;

/**
* @var string
*/
protected $domain;

/**
* Create a POT file for a WordPress plugin or theme.
*
Expand All @@ -70,7 +75,10 @@ class MakePotCommand extends WP_CLI_Command {
* : Plugin or theme slug. Defaults to the source directory's basename.
*
* [--domain=<domain>]
* : Text domain to look for in the source code. Defaults to the plugin/theme slug.
* : Text domain to look for in the source code. Defaults to the plugin/theme slug, unless the `--ignore-domain` option is used.
*
* [--ignore-domain]
* : Ignore the text domain completely and extract strings with any text domain.
*
* [--merge[=<file>]]
* : Existing POT file file whose content should be merged with the extracted strings.
Expand All @@ -96,6 +104,12 @@ public function __invoke( $args, $assoc_args ) {
$this->slug = Utils\get_flag_value( $assoc_args, 'slug', Utils\basename( $this->source ) );
$this->skip_js = Utils\get_flag_value( $assoc_args, 'skip-js', $this->skip_js );

$ignore_domain = Utils\get_flag_value( $assoc_args, 'ignore-domain', false );

if ( ! $ignore_domain ) {
$this->domain = Utils\get_flag_value( $assoc_args, 'domain', $this->slug );
}

if ( ! $this->source || ! is_dir( $this->source ) ) {
WP_CLI::error( 'Not a valid source directory!' );
}
Expand Down Expand Up @@ -144,7 +158,7 @@ public function __invoke( $args, $assoc_args ) {
$this->exclude = array_unique( $this->exclude );
}

if ( ! $this->makepot( Utils\get_flag_value( $assoc_args, 'domain', $this->slug ) ) ) {
if ( ! $this->makepot() ) {
WP_CLI::error( 'Could not generate a POT file!' );
}

Expand Down Expand Up @@ -245,11 +259,9 @@ protected function get_main_file_data() {
/**
* Creates a POT file and stores it on disk.
*
* @param string $domain The text domain to extract.
*
* @return bool True on success, false otherwise.
*/
protected function makepot( $domain ) {
protected function makepot() {
$this->translations = new Translations();

// Add existing strings first but don't keep headers.
Expand All @@ -267,7 +279,9 @@ protected function makepot( $domain ) {
// POT files have no Language header.
$this->translations->deleteHeader( Translations::HEADER_LANGUAGE );

$this->translations->setDomain( $domain );
if ( $this->domain ) {
$this->translations->setDomain( $this->domain );
}

$file_data = $this->get_main_file_data();

Expand Down
40 changes: 8 additions & 32 deletions src/PhpFunctionsScanner.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,64 +20,40 @@ public function saveGettextFunctions( Translations $translations, array $options
continue;
}

$domain = $context = $original = $plural = null;
$context = $plural = null;

switch ( $functions[ $name ] ) {
case 'text_domain':
case 'gettext':
if ( ! isset( $args[1] ) ) {
continue 2;
}

list( $original, $domain ) = $args;
list( $original, $domain ) = array_pad( $args, 2, null );
break;

case 'text_context_domain':
if ( ! isset( $args[2] ) ) {
continue 2;
}

list( $original, $context, $domain ) = $args;
list( $original, $context, $domain ) = array_pad( $args, 3, null );
break;

case 'single_plural_number_domain':
if ( ! isset( $args[3] ) ) {
continue 2;
}

list( $original, $plural, $number, $domain ) = $args;
list( $original, $plural, $number, $domain ) = array_pad( $args, 4, null );
break;

case 'single_plural_number_context_domain':
if ( ! isset( $args[4] ) ) {
continue 2;
}

list( $original, $plural, $number, $context, $domain ) = $args;
list( $original, $plural, $number, $context, $domain ) = array_pad( $args, 5, null );
break;

case 'single_plural_domain':
if ( ! isset( $args[2] ) ) {
continue 2;
}

list( $original, $plural, $domain ) = $args;
list( $original, $plural, $domain ) = array_pad( $args, 3, null );
break;

case 'single_plural_context_domain':
if ( ! isset( $args[3] ) ) {
continue 2;
}

list( $original, $plural, $context, $domain ) = $args;
list( $original, $plural, $context, $domain ) = array_pad( $args, 4, null );
break;

default:
// Should never happen.
\WP_CLI::error( sprintf( "Internal error: unknown function map '%s' for '%s'.", $functions[ $name ], $name ) );
}

if ( (string) $original !== '' && ( $domain === null || $domain === $translations->getDomain() ) ) {
if ( (string) $original !== '' && ( $domain === $translations->getDomain() || null === $translations->getDomain() ) ) {
$translation = $translations->insert( $context, $original, $plural );
$translation = $translation->addReference( $file, $line );

Expand Down