Communityコーディング&開発github.com

wp-plugin-i18n-release

WordPressプラグインを完全に国際化し、plugins.svn.wordpress.orgのSVNにリリースを公開します。ハードコードされたスペイン語の文字列を英語に書き換え、wp-cliで.potを生成し、初期翻訳(.po/.mo)を作成し、バージョンを同期してtrunkにコミットし、タグを作成します。

wp-plugin-i18n-release とは?

このスキルは、WordPressプラグインの完全な国際化(i18n)とSVNリリースを自動化するためのものです。主な機能は、PHPおよびJavaScriptファイル内のハードコードされたスペイン語の文字列を英語に書き換え、wp-cliを用いて.potファイルを生成し、初期翻訳ファイル(.po/.mo、例:中性スペイン語)を作成することです。さらに、バージョン番号を同期させ、SVN trunkへのコミットとタグ作成までを一貫して実行します。このスキルは、WordPress.orgでプラグインが承認された直後や、翻訳可能な文字列がスペイン語で記述されていて他の言語(フランス語、ドイツ語、日本語など)への翻訳を妨げている場合、または新しいリリースを公開する際に特に役立ちます。対応プラットフォームはplugins.svn.wordpress.orgで、Windows環境(TortoiseSVN、PHP、wp-cli)を前提としています。SVNチェックアウト、文字列修正、ビルド生成、コミット、タグ作成までの全工程をカバーし、開発用ファイルを除外したクリーンなビルドを提供します。

対応~Claude Code~Codex CLI~Cursor✓OpenCode
npx skills add https://github.com/leoarayas/agent-skills/tree/main/wp-plugin-i18n-release

Installed? Explore more コーディング&開発 skills: steipete/bluebubbles, steipete/eightctl, steipete/blucli · View all 6 →

お気に入りのAIに質問する

このエージェントスキルを事前に読み込んだ状態で新しいチャットを開きます。

ドキュメント

WordPressプラグイン:完全i18n + .org SVNへのリリース

使用するタイミング

  • WordPress.orgで承認されたばかりで、translate.wordpress.orgに対応する必要があるプラグイン。
  • 翻訳可能な文字列(__()、_e()、wp.i18n.__()など)がスペイン語でハードコードされており、GlotPressでの他言語(fr、de、pt、jaなど)への翻訳を妨げている場合。
  • 初めて初期翻訳や.potを追加する必要がある場合。
  • バージョンを上げてplugins.svn.wordpress.orgのSVNにリリースする場合。

前提条件

コンポーネント確認方法不足している場合
TortoiseSVN (svn.exe)Test-Path "C:\Program Files\TortoiseSVN\bin\svn.exe"https://tortoisesvn.net/downloads.html からインストール("command line tools"にチェック)
PHP 8.x (PATHに含まれていること)UNC以外のディレクトリで php --versionHerd legacyでも可。またはスタンドアロンPHP。
wp-cli.pharhttps://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar からダウンロードInvoke-WebRequest -Uri ... -OutFile wp-cli.phar
プラグインへのSVNアクセス[email protected]からの承認メール(SVN URL、ユーザー名、パスワードを含む)不足している場合はチームに依頼

完全なワークフロー

  1. 環境とプラグインを確認
  2. プラグインのSVNをチェックアウト
  3. コード内の翻訳可能な文字列を特定(PHP + JS)
  4. 文字列を英語に書き換え(技術的なセマンティクスを維持)
  5. .potを再生成(wp i18n make-pot)
  6. 初期翻訳の.po + .moを生成(例:中性スペイン語)
  7. 同期バージョンを更新(ヘッダー Version、定数、readme stable tag、CHANGELOG)
  8. 開発ファイルを除外したクリーンビルドを再生成(.distignore)
  9. trunkにコミット + SVNにタグを作成
  10. (オプション)Gitファイルを保持したままローカルディレクトリを同期

1. 環境とプラグインを確認

# WindowsのSVN(通常PATHに含まれていない。フルパスを使用するか追加する)
$env:Path = "$env:ProgramFiles\TortoiseSVN\bin;$env:Path"
svn --version

# PHP
php --version

コードに触れる前に、プラグインを読む:

  • プラグインヘッダー(Name、Version、Text Domain、Domain Path)
  • readme.txt(Stable tag、Changelog)
  • CHANGELOG.md(存在する場合)
  • includes/ と assets/ のPHP/JSファイル一覧

2. SVNのチェックアウト

$svnUser = '<wp-org-user>'       # WP.orgのユーザー名(大文字小文字区別)
$svnPass = 'svn_XXXXX...'     # profiles.wordpress.orgの「Account & Security」から取得
$slug    = 'mi-plugin'        # プラグインのスラッグ
$checkout = "C:\Temp\opencode\$slug-svn"

svn checkout --non-interactive --trust-server-cert `
  --username $svnUser --password $svnPass `
  "https://plugins.svn.wordpress.org/$slug" $checkout

SVNには既に trunk/、tags/、assets/ が含まれています。初めてのリリースをアップロードしたばかりの場合、tags/ は空で trunk/ も空(初期trunkで作成されたばかり)です。

3. 翻訳可能な文字列を特定

i18n関数の呼び出しをすべて特定します。以下のパターンで grep を使用します。

# PHP
Select-String -Path 'includes/*.php' -Pattern '__\(|_e\(|_x\(|esc_html__\(|esc_attr__\(|esc_html_e\(|esc_attr_e\(|_n\(|_nx\('

# JS(wp.i18n または関数なしのハードコードされた文字列)
Select-String -Path 'assets/js/*.js' -Pattern 'wp\.i18n|__\('
Select-String -Path 'assets/js/*.js' -Pattern '"[^"]{6,80}"'   # ハードコードされた文字列を検出

よくあるアンチパターン:JS内で連結されたHTML内のスペイン語の文字列(例:html += '<option>Todas</option>';)。直接英語に書き換えることも有効ですが、ランタイムで翻訳可能にするには wp.i18n.__() を使用する方が適切です。

4. 文字列を英語に書き換え

厳格なルール:

  1. i18n関数の最初の引数のみ翻訳します。text-domain(2番目の引数)には触れないでください。
  2. i18n呼び出し以外には触れないでください。
  3. PHPの形式(スペース、引用符、括弧)は変更しないでください。
  4. ExampleStore、WooCommerce、API、Correlation ID、Premium、JSON、HTTP、URL、CLP などの技術用語は英語のまま維持します(すでに固有名詞/頭字語です)。
  5. sprintf/printfのプレースホルダー(%s、%d、%1$s など)は正確に保持します。
  6. 文字列がすでに英語になっている場合は、変更しないでください。

推奨翻訳表(コンテキストに応じて調整):

スペイン語英語
"Activo""Enabled"
"Título""Title"
"Configurar""Configure"
"Guardar""Save"
"Eliminar""Delete"
"Comuna""Commune"
"Región""Region"
"Selecciona una región""Select a region"
"Sin reglas guardadas""No saved rules"
"Configura la URL de API y el token""Configure API URL and token"
"Diagnóstico ejecutado correctamente""Diagnostic executed successfully"
"No se pudo {動詞}""Could not {動詞}"
"Debes ingresar X""You must enter X"
"Cotización API recibida""API quote received"
"Tarifa por defecto (CLP)""Default rate (CLP)"

大規模なファイルの場合は、エージェントに正確な指示と翻訳表を委任します。

5. wp-cliで.potを再生成

# プラグインディレクトリから(ローカルミラー)
$wpCli = 'C:\Temp\opencode\wp-cli.phar'
php $wpCli i18n make-pot . "languages/mi-plugin.pot" --domain="mi-plugin"

.pot は /languages/ に <text-domain>.pot という名前で配置する必要があります。

6. 翻訳.po + .moを作成

重要な決定:どのロケールを使用するか?地域バリエーションなしでプラグインをすべてのスペイン語話者に自動翻訳させるには、<text-domain>-es.po(ルート es)を使用します。WordPressはカスケードフォールバックを行います:es_CL → es → 英語。

推奨戦略:

  • es.po/.mo(ルート)→ es_CL、es_ES、es_MX、es_AR、es_PEなどに対応。
  • (後日オプション)チリ限定の es_CL.po/.mo(地域の表現用)。

.poを生成:.pot を読み取り、EN→ESの翻訳配列を適用するPHPスクリプトを使用します。アクセント付き文字には mb_chr(0x00f3) を使用します(WindowsのPHPはUTF-8リテラルでコードページの問題が発生します)。

// build-es.php
declare(encoding='UTF-8');
$pot = file_get_contents('languages/mi-plugin.pot');
$po_es = 'languages/mi-plugin-es.po';

// アクセント付き文字にmb_chrをプリロード
function A() { return mb_chr(0x00e1); } // á
function E() { return mb_chr(0x00e9); } // é
function O() { return mb_chr(0x00f3); } // ó
// など

$t = [
    "Configure API URL and token" => "Configura la URL de API y el token",
    // ...
];

$header = "msgid \"\"\nmsgstr \"\"\n"
        . "\"Project-Id-Version: Mi Plugin 1.0.0\\n\"\n"
        . "\"Language-Team: Español (neutro) <>\\n\"\n"
        . "\"Language: es\\n\"\n"
        . "\"Plural-Forms: nplurals=2; plural=(n != 1);\\n\"\n";

// .potをパースし、$tでmsgstrを入力、.poを書き込む
// (完全なロジック:wp-plugin-i18n-release/build-es.phpを参照)

.moをコンパイル:

php $wpCli i18n make-mo languages/

これにより、自動的に languages/<text-domain>-es.mo が作成されます。

7. 同期バージョンを更新

4つのファイルを更新します:

// 1. my-plugin.php (ヘッダー)
 * Version: 1.1.0

// 2. my-plugin.php (定数)
define('PLUGIN_VERSION', '1.1.0');

// 3. readme.txt
Stable tag: 1.1.0
/* + == Changelog == に新しいエントリ */

// 4. CHANGELOG.md
## [1.1.0] - 2026-09-14
### Changed
- ...

8. クリーンビルドを再生成(開発ファイルを除外)

プラグインの .distignore で除外するものが定義されています。存在しない場合は、次の標準リストを使用します。

$exclude = @('.git','.github','.gitignore','.gitattributes','.distignore',
             '.idea','.DS_Store','.release-build','bin','node_modules',
             'tests','vendor/bin','phpcs.xml*','phpunit.xml*',
             '.phpunit.result.cache','*.lock','*.log','*.zip',
             'README.md','RELEASING.md','Makefile','.pr-body-*.md')

# 出力先をクリーンアップし、全てコピー、除外ファイルを削除
$src  = 'ruta/espejo/plugin'
$dist = 'ruta/build/plugin'
Copy-Item -Path "$src\*" -Destination $dist -Recurse -Force
foreach ($pat in $exclude) {
  Get-ChildItem -Path $dist -Recurse -Force -Filter $pat -ErrorAction SilentlyContinue | Remove-Item -Recurse -Force
}

9. trunkにコミット + タグを作成

$env:Path = "$env:ProgramFiles\TortoiseSVN\bin;$env:Path"

# trunkをクリーンビルドで置き換え
$trunk = "C:\Temp\opencode\$slug-svn\trunk"
Get-ChildItem -Path $trunk -Force | Where-Object { $_.Name -ne '.svn' } | Remove-Item -Recurse -Force
Copy-Item -Path "$dist\*" -Destination $trunk -Recurse -Force

# svn add + commit
Set-Location $trunk
svn add --force --depth infinity .

svn commit --non-interactive --trust-server-cert `
  --username $svnUser --password $svnPass `
  -m "Release 1.1.0: English source strings, full i18n rewrite, initial Spanish (es) translation"

# タグを作成 (リモートsvn copy)
svn copy --non-interactive --trust-server-cert `
  --username $svnUser --password $svnPass `
  -m "Tagging 1.1.0" `
  "https://plugins.svn.wordpress.org/$slug/trunk" `
  "https://plugins.svn.wordpress.org/$slug/tags/1.1.0"

リモートタグの後、ローカル更新を強制します(新しいタグはワーキングコピーに完全には反映されません)。

svn cleanup
svn update --depth infinity --force --non-interactive --trust-server-cert `
  --username $svnUser --password $svnPass "$trunk/../"

10. (オプション)ローカルディレクトリを同期

SVNエクスポートにないファイル(.git/、.gitignore、tests/、bin/など)を保持します。

$local    = 'C:\Users\...\wp-content\plugins\mi-plugin'
$exportDir = 'C:\Users\...\export-1.1.0'

# 新しく作成されたタグをエクスポート
svn export "https://plugins.svn.wordpress.org/$slug/tags/1.1.0" $exportDir

# ローカルからリリースファイルのみを削除し、その他は保持
$releaseNames = (Get-ChildItem $exportDir -Force).Name
foreach ($name in $releaseNames) {
  $localPath = Join-Path $local $name
  if (Test-Path $localPath) { Remove-Item $localPath -Recurse -Force }
}

# エクスポートをローカルにコピー
Copy-Item -Path "$exportDir\*" -Destination $local -Recurse -Force

11. 最終確認

# ローカルのバージョン確認
Write-Host "header: " (Get-Content "$local\mi-plugin.php" | Select-String -Pattern 'Version:' | Select-Object -First 1).ToString().Trim()
Write-Host "readme: " (Get-Content "$local\readme.txt" | Select-String -Pattern 'Stable tag:' | Select-Object -First 1).ToString().Trim()

# リモートSVNの確認
svn ls --recursive "https://plugins.svn.wordpress.org/$slug/tags/1.1.0/"

WordPress.orgの重要ルール

概念ルール
Text Domainプラグインのスラッグと同一でなければなりません(例:mi-plugin)。スラッグを変更するにはプラグインの再承認が必要です。絶対に変更しないでください。
Domain PathWordPress.orgが.potを見つけるためには /languages/ を指定します。
Plugin Name ヘッダー先頭にサードパーティの商標を含めないでください(WP.orgのレビューで拒否されます)。
readme.txtWP.orgはこのファイルをパースします(README.mdではありません)。Stable tag はバージョンと一致している必要があります。
SVNレイアウト/trunk/(開発)、/tags/X.Y.Z/(リリース)、/assets/(バナー、アイコン、スクリーンショット)
SVNはリリースシステム"ready-to-useバージョンのみをプッシュ"。trunkへの頻繁な開発コミットは避けてください。
翻訳のフォールバックWPはカスケード検索:text-domain-locale.mo → text-domain.mo → text-domain-en_US.mo(コア)。ルートロケール es はすべての es_XX バリアントに対応します。

よくある問題とエラー(Gotchas)

PowerShellとUNCパス

CWDがUNCパス(\\server\share)の場合、PHPや多くのバイナリが失敗します。コマンドを実行する前に:

Set-Location C:\Users\<ユーザー名>   # または任意のローカルディレクトリ
php $wpCli ...                # これで動作

Windows PHPでのアクセント付き文字のエンコーディング

WindowsのPHPはスクリプト内のUTF-8リテラルで問題が発生します。解決策:各アクセント付き文字に mb_chr(0x00f3) を使用します。

"Obtener pa" . mb_chr(0x00ed) . "s"  // "Obtener país"

PowerShellはまた、Get-Content でアクセント付き文字の代わりに ? を表示する場合があります。ファイルのバイトを確認し、レンダリングを確認しないでください。

$bytes = [System.IO.File]::ReadAllBytes('archivo.po')
# 0xC3 0xB3 ('ó'のUTF-8) を探す

新しいタグの後、SVNワーキングコピーが空に見える

SVNはtrunkとタグ間でファイルを重複排除します(同じ「blob」)。リモートで svn copy を実行すると、ファイルはサーバー上に表示されますが、ローカルのワーキングコピーにはプレースホルダーがあります。解決策:svn cleanup + svn update --depth infinity --force。

svn.exeがPATHにない

TortoiseSVNは C:\Program Files\TortoiseSVN\bin\ にインストールされますが、デフォルトで svn.exe をPATHに追加しません。一時的な解決策:

$env:Path = "$env:ProgramFiles\TortoiseSVN\bin;$env:Path"

または、ユーザーのPATHに永続的に追加します。

プラグインがヘッダーにスペイン語の文字列を使用している

プラグインヘッダーの文字列(Plugin Name、Descriptionなど)は翻訳されません。しかし、wp i18nがそれらを.potに含めた場合は、msgstr ""(空)のままにしておきます。WP.orgとGlotPressはこれらが翻訳されないことを認識しています。

GlotPressが管理するロケールの.po/.moを含めない

GlotPressが(コミュニティを通じて)プラグインの翻訳を持つようになると、WP.orgが自動的に.moを提供します。初期の.po/.moは初期シードのみです。GlotPressと競合しないでください。


リリースによって変更されるファイル(チェックリスト)

  • my-plugin.php — ヘッダー Version + PLUGIN_VERSION
  • readme.txt — Stable tag + Changelogのエントリ
  • CHANGELOG.md — 新しいエントリ
  • languages/<text-domain>.pot — 再生成
  • languages/<text-domain>-es.po — 生成
  • languages/<text-domain>-es.mo — コンパイル
  • .distignore — 必要に応じて確認/更新

Individual skills in this repo

This repo contains 2 individual skills — each has its own dedicated page.

関連スキル