LESSON 8 ⏱️ 12 min read

Packaging, i18n & WordPress.org Submission

Preparing for Distribution

Before releasing your plugin, ensure:

  1. ✅ Code follows WordPress Coding Standards
  2. ✅ All strings are translatable
  3. ✅ readme.txt is complete
  4. ✅ No debug code or console.log statements
  5. ✅ Vendor files are production-ready

The readme.txt File

WordPress.org requires a specific readme format:

=== Task Manager ===
Contributors: yourwporgusername
Donate link: https://example.com/donate
Tags: tasks, todo, project management, productivity
Requires at least: 6.0
Tested up to: 6.4
Requires PHP: 8.0
Stable tag: 1.0.0
License: GPLv2 or later
License URI: https://www.gnu.org/licenses/gpl-2.0.html

A modern task management plugin built with OOP and REST API support.

== Description ==

Task Manager is a powerful yet simple plugin for managing tasks directly in your WordPress admin.

**Features:**

* Modern OOP architecture
* REST API for integrations
* Custom database for performance
* Role-based permissions
* AJAX-powered interface

**Pro Features (Premium):**

* Email notifications
* Recurring tasks
* Team assignments
* Kanban board view

== Installation ==

1. Upload the `task-manager` folder to `/wp-content/plugins/`
2. Activate the plugin through the 'Plugins' menu in WordPress
3. Go to Tasks in the admin menu to get started

== Frequently Asked Questions ==

= Can I import tasks from other plugins? =

Yes, go to Tasks → Settings → Import for migration options.

= Is the REST API secure? =

Yes, all endpoints require authentication and proper capabilities.

== Screenshots ==

1. Main task dashboard
2. Adding a new task
3. Settings page
4. REST API in action

== Changelog ==

= 1.0.0 =
* Initial release

= 0.9.0 =
* Beta release for testing

== Upgrade Notice ==

= 1.0.0 =
First stable release. Safe to use in production.
readme.txt Tips:
  • Stable tag must match your plugin version
  • Tested up to should be the latest WordPress version
  • Screenshots must be in /assets/ folder as screenshot-1.png, etc.

Internationalization (i18n)

Making your plugin translatable:

Wrapping Strings

// Simple string
__( 'Task Manager', 'task-manager' )

// Echo directly
_e( 'Settings', 'task-manager' )

// With placeholders
sprintf(
    __( 'Task %s has been created.', 'task-manager' ),
    $task->title
)

// Plural forms
sprintf(
    _n(
        '%d task completed',
        '%d tasks completed',
        $count,
        'task-manager'
    ),
    $count
)

// Context for translators
_x( 'Post', 'verb', 'task-manager' )  // To post something
_x( 'Post', 'noun', 'task-manager' )  // A blog post

// Escape while translating
esc_html__( 'Title', 'task-manager' )
esc_attr__( 'Click here', 'task-manager' )

Loading Text Domain

public function load_textdomain(): void {
    load_plugin_textdomain(
        'task-manager',
        false,
        dirname( plugin_basename( TM_PLUGIN_FILE ) ) . '/languages'
    );
}
add_action( 'init', [ $this, 'load_textdomain' ] );

Generating POT File

Use WP-CLI to generate the translation template:

wp i18n make-pot . languages/task-manager.pot --domain=task-manager

Or use the grunt-wp-i18n package in your build process.

Build Process

Create a build script to prepare for release:

#!/bin/bash
# build.sh

VERSION=$1
SLUG="task-manager"

if [ -z "$VERSION" ]; then
    echo "Usage: ./build.sh 1.0.0"
    exit 1
fi

# Create build directory
rm -rf build/
mkdir -p build/$SLUG

# Copy files
cp -r src/ build/$SLUG/src/
cp -r assets/ build/$SLUG/assets/
cp -r templates/ build/$SLUG/templates/
cp -r languages/ build/$SLUG/languages/
cp $SLUG.php build/$SLUG/
cp readme.txt build/$SLUG/
cp uninstall.php build/$SLUG/
cp composer.json build/$SLUG/

# Install production dependencies
cd build/$SLUG
composer install --no-dev --optimize-autoloader
rm composer.json composer.lock

# Remove dev files
find . -name "*.map" -delete
find . -name ".DS_Store" -delete

# Create ZIP
cd ..
zip -r $SLUG-$VERSION.zip $SLUG

echo "Created: build/$SLUG-$VERSION.zip"

WordPress.org Submission

Submit Your Plugin

  1. Go to https://wordpress.org/plugins/developers/add/
  2. Upload your plugin ZIP
  3. Wait for review (usually 1-5 days)
  4. Address any feedback from reviewers

Common Review Issues

IssueSolution
Direct file accessAdd if ( ! defined( 'ABSPATH' ) ) exit;
Sanitization missingUse sanitize_() functions
Escaping missingUse esc_() functions
Nonce verificationAdd wp_verify_nonce() checks
Calling remote filesUse wp_remote_get() instead
Undeclared variablesInitialize all variables

After Approval

Once approved, you get SVN access:

# Checkout your plugin repository
svn co https://plugins.svn.wordpress.org/task-manager task-manager-svn

# Copy files to trunk
cp -r build/task-manager/* task-manager-svn/trunk/

# Add new files
svn add --force task-manager-svn/trunk/*

# Commit to trunk
cd task-manager-svn
svn ci -m "Version 1.0.0 release" --username yourwporgusername

# Create version tag
svn cp trunk tags/1.0.0
svn ci -m "Tagging version 1.0.0" --username yourwporgusername

Automated Releases with GitHub Actions

# .github/workflows/deploy.yml
name: Deploy to WordPress.org

on:
  release:
    types: [published]

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      
      - name: Setup PHP
        uses: shivammathur/setup-php@v2
        with:
          php-version: '8.2'
          tools: composer
      
      - name: Install dependencies
        run: composer install --no-dev --optimize-autoloader
      
      - name: WordPress Plugin Deploy
        uses: 10up/action-wordpress-plugin-deploy@stable
        env:
          SVN_USERNAME: ${{ secrets.SVN_USERNAME }}
          SVN_PASSWORD: ${{ secrets.SVN_PASSWORD }}
          SLUG: task-manager

Version Management

Follow semantic versioning:

  • MAJOR (2.0.0) – Breaking changes
  • MINOR (1.1.0) – New features, backward compatible
  • PATCH (1.0.1) – Bug fixes

Update version in:

  1. Main plugin file header
  2. Plugin constant (TM_VERSION)
  3. readme.txt Stable tag
  4. package.json if using npm

Congratulations!

You've completed the Modern WordPress Plugin Development tutorial!

What You've Learned

  • ✅ Plugin architecture with OOP and namespaces
  • ✅ PSR-4 autoloading with Composer
  • ✅ WordPress hooks system
  • ✅ Admin pages with Settings API
  • ✅ Custom database tables
  • ✅ REST API development
  • ✅ Security best practices
  • ✅ Internationalization
  • ✅ Packaging and distribution

Next Steps

  1. Add unit tests with PHPUnit and WP_Mock
  2. Set up CI/CD with GitHub Actions
  3. Create documentation for your plugin
  4. Build a pro version with additional features
🎯 Tutorial Complete! You're now ready to build and distribute professional WordPress plugins.
🎉

Tutorial Complete!

You've finished all lessons in this series.

← Back to Tutorial Overview