WordPress Plugin Creation

User
Create WordPress Standard plugin to submit in wordpress
Assistant
Here's a complete, clean, and structured example of a WordPress standard plugin ready to submit to the WordPress repository. This plugin demonstrates basic best practices and a clean, organized file structure.
Assistant
### File structure for submission:

my-first-wp-plugin/
├── assets/
│   ├── css/
│   │   └── style.css
│   └── js/
│       └── script.js
├── languages/
│   └── my-first-wp-plugin.pot
├── my-first-wp-plugin.php
└── readme.txt

### Example `readme.txt` for WordPress repository:

=== My First WP Plugin ===
Contributors: yourname
Tags: example, shortcode, beginner
Requires at least: 5.0
Tested up to: 6.5
Requires PHP: 7.4
Stable tag: 1.0.0
License: GPLv2 or later
License URI: https://www.gnu.org/licenses/gpl-2.0.html

A simple WordPress plugin demonstrating basic structure and submission standards.

== Description ==

This plugin is designed as an introductory example demonstrating basic plugin structure, shortcode usage, and script enqueueing in WordPress.

== Installation ==

1. Upload the plugin files to the `/wp-content/plugins/my-first-wp-plugin` directory.
2. Activate the plugin through the 'Plugins' screen in WordPress.
3. Use the shortcode `[mf_wp_message message="Custom message"]` to display a custom message.

== Frequently Asked Questions ==

= Can I customize the message displayed by the shortcode? =
Yes, use the attribute `message`, e.g., `[mf_wp_message message="Your message"]`.

== Changelog ==

= 1.0.0 =
* Initial release.

== Upgrade Notice ==
Initial release.

### Submission Steps:

1. Ensure your plugin is thoroughly tested.
2. Include proper documentation (`readme.txt` and inline documentation).
3. Use translation-ready text strings.
4. Submit your plugin via the [WordPress plugin repository submission page](https://wordpress.org/plugins/developers/add/).

This provides a clean, professional structure ideal for the WordPress plugin repository.

User
Assistant
Your current Elementor Animation Text Widget plugin code is solid and structured properly for WordPress standards. To ensure it fully meets the WordPress plugin repository submission guidelines, consider the following refinements and additions:

### Improved Plugin Structure:
Your plugin's current structure should look like this:

elementor-animation-text-widget/
├── fonts/
│   ├── custom-font.css
│   └── [your font files e.g., .woff2, .woff]
├── languages/
│   └── eatw.pot
├── widgets/
│   └── class-variable-font-widget.php
├── elementor-animation-text-widget.php
└── readme.txt

### Recommended Enhancements for Submission:

### 1. Proper Enqueueing in Elementor Editor Mode
To enqueue scripts/styles in Elementor editor mode as well as on the frontend, update your enqueue function:

function eatw_enqueue_custom_font() {
    wp_enqueue_style(
        'eatw-custom-font',
        plugin_dir_url( __FILE__ ) . 'fonts/custom-font.css',
        [],
        EATW_VERSION
    );
}
add_action( 'wp_enqueue_scripts', 'eatw_enqueue_custom_font' );
add_action( 'elementor/editor/before_enqueue_scripts', 'eatw_enqueue_custom_font' );

### 2. Load Plugin Textdomain (Internationalization)

Add this function to load your plugin's textdomain for translations:

function eatw_load_textdomain() {
    load_plugin_textdomain( 'eatw', false, basename( dirname( __FILE__ ) ) . '/languages' );
}
add_action( 'plugins_loaded', 'eatw_load_textdomain' );

### 3. Provide `readme.txt` file:
Use this sample format as your `readme.txt` file:

=== Elementor Animation Text Widget ===
Contributors: neerajtiwari
Tags: elementor, widget, animation, typography, fonts
Requires at least: 5.0
Tested up to: 6.5
Requires PHP: 7.4
Stable tag: 1.0
License: GPL2+
License URI: https://www.gnu.org/licenses/gpl-2.0.txt

Adds a custom Elementor widget that applies animated variable font effects with selectable animation styles.

== Description ==

Elementor Animation Text Widget lets you easily add beautiful animated typography to your Elementor pages using variable fonts. Select different animation effects to enhance visual engagement.

== Installation ==

1. Upload `elementor-animation-text-widget` to the `/wp-content/plugins/` directory.
2. Activate the plugin through the 'Plugins' screen in WordPress.
3. Ensure Elementor is installed and activated.

== Frequently Asked Questions ==

= Does it require Elementor? =
Yes, this plugin requires Elementor to be installed and activated.

== Screenshots ==

1. Widget settings in Elementor editor.
2. Example animation effect.

== Changelog ==

= 1.0 =
* Initial release with custom font and animation support.

== Upgrade Notice ==
Initial release.

### 4. POT File for Translation (`eatw.pot`)
Use tools like [Poedit](https://poedit.net/) to generate your POT file based on your PHP files and strings.

### Final Plugin File (updated & polished)
Your updated and polished main plugin file (`elementor-animation-text-widget.php`) would look like this:

<?php
/**
 * Plugin Name: Elementor Animation Text Widget
 * Plugin URI: https://yourwebsite.com/elementor-animation-text-widget
 * Description: Adds a custom Elementor widget that applies animated variable font effects with selectable animation styles.
 * Version: 1.0
 * Author: Neeraj Tiwari
 * Author URI: https://yourwebsite.com
 * License: GPL2+
 * License URI: https://www.gnu.org/licenses/gpl-2.0.txt
 * Text Domain: eatw
 * Domain Path: /languages
 */

if ( ! defined( 'ABSPATH' ) ) exit;

define( 'EATW_VERSION', '1.0.0' );
define( 'EATW_PLUGIN_DIR', plugin_dir_path( __FILE__ ) );
define( 'EATW_PLUGIN_URL', plugin_dir_url( __FILE__ ) );

// Activation hook: Check Elementor dependency
function eatw_activation_check() {
    if ( ! did_action( 'elementor/loaded' ) ) {
        deactivate_plugins( plugin_basename( __FILE__ ) );
        wp_die(
            __( 'This plugin requires Elementor to be installed and activated.', 'eatw' ),
            __( 'Plugin dependency check', 'eatw' ),
            [ 'back_link' => true ]
        );
    }
}
register_activation_hook( __FILE__, 'eatw_activation_check' );

// Load plugin textdomain
function eatw_load_textdomain() {
    load_plugin_textdomain( 'eatw', false, basename( dirname( __FILE__ ) ) . '/languages' );
}
add_action( 'plugins_loaded', 'eatw_load_textdomain' );

// Register Elementor Widget
function eatw_register_widget( $widgets_manager ) {
    require_once( __DIR__ . '/widgets/class-variable-font-widget.php' );
    $widgets_manager->register( new Elementor_Variable_Font_Widget() );
}
add_action( 'elementor/widgets/register', 'eatw_register_widget' );

// Enqueue custom fonts in frontend and editor
function eatw_enqueue_custom_font() {
    wp_enqueue_style(
        'eatw-custom-font',
        EATW_PLUGIN_URL . 'fonts/custom-font.css',
        [],
        EATW_VERSION
    );
}
add_action( 'wp_enqueue_scripts', 'eatw_enqueue_custom_font' );
add_action( 'elementor/editor/before_enqueue_scripts', 'eatw_enqueue_custom_font' );

// Register custom font groups for Elementor
add_filter( 'elementor/fonts/groups', function( $groups ) {
    $groups['eatw_custom_fonts'] = __( 'Eatw Custom Fonts', 'eatw' );
    return $groups;
});

// Assign custom fonts to group
add_filter( 'elementor/fonts/additional_fonts', function( $fonts ) {
    $fonts['Neue Metana'] = 'eatw_custom_fonts';
    $fonts['Compressa VF'] = 'eatw_custom_fonts';
    return $fonts;
});

### Submission to WordPress.org:

To submit your plugin officially to the WordPress plugin repository:

1. Zip your plugin folder (`elementor-animation-text-widget`) containing all necessary files.
2. Visit [WordPress Plugin Repository Submission Page](https://wordpress.org/plugins/developers/add/).
3. Submit your plugin for review, clearly describing its purpose and functionality.

This refined structure will help you smoothly pass the WordPress plugin review process.

User
=== Animation Text Widget ===
Contributors: neerajtiwari
Tags: elementor, widget, animation, typography, fonts
Requires at least: 5.0
Tested up to: 6.5
Requires PHP: 7.4+
Stable tag: 1.0
License: GPL2+
License URI: https://www.gnu.org/licenses/gpl-2.0.txt

Adds a custom Elementor widget that applies animated variable font effects with selectable animation styles.

== Description ==

Elementor Animation Text Widget lets you easily add beautiful animated typography to your Elementor pages using variable fonts. Select different animation effects to enhance visual engagement.

== Installation ==

1. Upload `elementor-animation-text-widget` to the `/wp-content/plugins/` directory.
2. Activate the plugin through the 'Plugins' screen in WordPress.
3. Ensure Elementor is installed and activated.
4. Go to Elementor > Settings > Widgets and search for 'Animation Text Widget' or click on the plugin's icon to install it.

== Frequently Asked Questions ==

= Does it require Elementor? =
Yes, this plugin requires Elementor to be installed and activated.

== Screenshots ==

1. Widget settings in Elementor editor.
2. Example animation effect.

== Changelog ==

= 1.0 =
* Initial release with custom font and animation support.

== Upgrade Notice ==
Initial release.

Results of Automated Plugin Scanning: Fail

readme.txt ERROR: outdated_tested_upto_header: Tested up to: 6.5 < 6.7. The "Tested up to" value in your plugin is not set to the current version of WordPress. This means your plugin will not show up in searches, as we require plugins to be compatible and documented as tested up to the most recent version of WordPress.
elementor-animation-text-widget.php WARNING: textdomain_mismatch: The “Text Domain” header in the plugin file does not match the slug. Found “eatw”, expected “animation-text-widget”.
The above may contain false-positives. If you believe an error or warning is incorrect or a false-positive, please do not work around it. A reviewer will manually confirm this during the review process.

Note: While the automated plugin scan is based on the Plugin Review Guidelines, it is not a complete review. A successful result from the scan does not guarantee that the plugin will be approved, only that it is sufficient to be reviewed. All submitted plugins are checked manually to ensure they meet security and guideline standards before approval.

Assistant
To resolve the automated plugin scanning issues, make these two specific changes:

### ✅ **Fix #1: Update `readme.txt` to the Latest WordPress Version**

Update the line in your `readme.txt`:

- Tested up to: 6.5
+ Tested up to: 6.7

This indicates your plugin is compatible with the latest WordPress version.

### ✅ **Fix #2: Match Text Domain to Plugin Slug**

The slug is derived from your plugin’s folder name, e.g.:

elementor-animation-text-widget

Thus, your text domain in the main plugin file should match:

- Text Domain: eatw
+ Text Domain: elementor-animation-text-widget

Also update your textdomain loading code accordingly:

function eatw_load_textdomain() {
    load_plugin_textdomain( 'elementor-animation-text-widget', false, basename( dirname( __FILE__ ) ) . '/languages' );
}
add_action( 'plugins_loaded', 'eatw_load_textdomain' );

And your filters:

// Register custom font groups for Elementor
add_filter( 'elementor/fonts/groups', function( $groups ) {
    $groups['eatw_custom_fonts'] = __( 'Eatw Custom Fonts', 'elementor-animation-text-widget' );
    return $groups;
});

### ✅ **Updated Corrected `readme.txt`:**

=== Animation Text Widget ===
Contributors: neerajtiwari
Tags: elementor, widget, animation, typography, fonts
Requires at least: 5.0
Tested up to: 6.7
Requires PHP: 7.4+
Stable tag: 1.0
License: GPL2+
License URI: https://www.gnu.org/licenses/gpl-2.0.txt

Adds a custom Elementor widget that applies animated variable font effects with selectable animation styles.

== Description ==

Elementor Animation Text Widget lets you easily add beautiful animated typography to your Elementor pages using variable fonts. Select different animation effects to enhance visual engagement.

== Installation ==

1. Upload `elementor-animation-text-widget` to the `/wp-content/plugins/` directory.
2. Activate the plugin through the 'Plugins' screen in WordPress.
3. Ensure Elementor is installed and activated.
4. Go to Elementor > Settings > Widgets and search for 'Animation Text Widget' or click on the plugin's icon to activate it.

== Frequently Asked Questions ==

= Does it require Elementor? =
Yes, this plugin requires Elementor to be installed and activated.

== Screenshots ==

1. Widget settings in Elementor editor.
2. Example animation effect.

== Changelog ==

= 1.0 =
* Initial release with custom font and animation support.

== Upgrade Notice ==
Initial release.

### ✅ **Corrected Main Plugin File Header Example:**

<?php
/**
 * Plugin Name: Elementor Animation Text Widget
 * Plugin URI: https://yourwebsite.com/elementor-animation-text-widget
 * Description: Adds a custom Elementor widget that applies animated variable font effects with selectable animation styles.
 * Version: 1.0
 * Author: Neeraj Tiwari
 * Author URI: https://yourwebsite.com
 * License: GPL2+
 * License URI: https://www.gnu.org/licenses/gpl-2.0.txt
 * Text Domain: elementor-animation-text-widget
 * Domain Path: /languages
 */

After these corrections, re-submit your plugin, and it should pass the automated checks and move forward smoothly for manual review.

User
158 41 ERROR WordPress.Security.EscapeOutput.OutputNotEscaped All output should be run through an escaping function (see the Security sections in the WordPress Developer Handbooks), found 'EATW_PLUGIN_URL'.

<script>
window.effect1ElementId = '<?php echo esc_js($effect2_id); ?>';
        window.effectFontSize = '<?php echo esc_js($font_size); ?>';
        window.effectTag = '<?php echo esc_js($tag); ?>';
</script>
<script>
js/effect1.js" >
</script>
<script>

</script>

';
self::$script_loaded = true;
}
if(!is_admin())
{
?>

<script>
window.effectFontSize = '<?php echo esc_js($font_size); ?>';
</script>
<script>
js/effect2.js" >
</script>
Assistant
The issue you're facing:

ERROR: WordPress.Security.EscapeOutput.OutputNotEscaped

is because WordPress coding standards require URLs and all outputs to be escaped to prevent potential vulnerabilities (like XSS attacks).

You need to wrap your constant (`EATW_PLUGIN_URL`) in an escaping function specifically for URLs: `esc_url()`.

### ✅ **Fixing the Issue:**

Replace this:

<link rel="stylesheet" href="<?php echo EATW_PLUGIN_URL; ?>css/effect1.css" />

with this (escaping URL):

<link rel="stylesheet" href="<?php echo esc_url( EATW_PLUGIN_URL . 'css/effect1.css' ); ?>" />

Apply the same fix for all similar lines throughout your code:

### ✅ **Corrected Code Examples:**

**Stylesheets:**

<link rel="stylesheet" href="<?php echo esc_url( EATW_PLUGIN_URL . 'css/effect1.css' ); ?>" />
<link rel="stylesheet" href="<?php echo esc_url( EATW_PLUGIN_URL . 'css/effect2.css' ); ?>" />

**Scripts:**

<script src="<?php echo esc_url( EATW_PLUGIN_URL . 'js/effect1.js' ); ?>"></script>
echo '<script src="' . esc_url( EATW_PLUGIN_URL . 'js/dat.gui.min.js' ) . '"></script>';
<script src="<?php echo esc_url( EATW_PLUGIN_URL . 'js/effect2.js' ); ?>"></script>

### ✅ **Example of Final Corrected Rendering Method:**

Here's a cleaned-up version of your entire `render()` method with correct escaping:

protected function render() {
    $settings = $this->get_settings_for_display();
    $text     = esc_html( $settings['content'] );
    $tag      = tag_escape( $settings['heading_tag'] );
    $font_size = '75px';

    if ( isset( $settings['text_typography_font_size']['size'], $settings['text_typography_font_size']['unit'] ) ) {
        $font_size = esc_attr( $settings['text_typography_font_size']['size'] . $settings['text_typography_font_size']['unit'] );
    }

    global $post;
    $current_page_id = is_object( $post ) ? (int) $post->ID : 0;

    if ( $settings['font_effect'] == 'effect-one' ) {
        ?>
        <link rel="stylesheet" href="<?php echo esc_url( EATW_PLUGIN_URL . 'css/effect1.css' ); ?>" />
        <?php $effect2_id = esc_attr( 'effect2' . $this->get_id() ); ?>
        <div class="hero-content" id="<?php echo $effect2_id; ?>">
            <div class="hero-title">
                <<?php echo $tag; ?> id="titlefont2" class="variable-font-content"><?php echo $text; ?></<?php echo $tag; ?>>
            </div>
        </div>
        <?php if ( ! is_admin() ) : ?>
            <script>
                window.effect1ElementId = '<?php echo esc_js( $effect2_id ); ?>';
                window.effectFontSize   = '<?php echo esc_js( $font_size ); ?>';
                window.effectTag        = '<?php echo esc_js( $tag ); ?>';
            </script>
            <script src="<?php echo esc_url( EATW_PLUGIN_URL . 'js/effect1.js' ); ?>"></script>
        <?php endif;
    } else {
        ?>
        <link rel="stylesheet" href="<?php echo esc_url( EATW_PLUGIN_URL . 'css/effect2.css' ); ?>" />
        <?php
        $unique_id = esc_attr( 'effect-text-' . sprintf( '%02d', $this->get_id() ) . '-page-' . $current_page_id );
        ?>
        <div id="fit" class="<?php echo $unique_id; ?> fit-container" data-page-id="<?php echo esc_attr( $current_page_id ); ?>" data-font-size="<?php echo esc_attr( $font_size ); ?>">
            <<?php echo $tag; ?> class="<?php echo $unique_id; ?> title variable-font-content"><?php echo $text; ?></<?php echo $tag; ?>>
        </div>
        <?php
        if ( ! self::$script_loaded && ! is_admin() ) {
            echo '<script src="' . esc_url( EATW_PLUGIN_URL . 'js/dat.gui.min.js' ) . '"></script>';
            self::$script_loaded = true;
        }
        if ( ! is_admin() ) :
            ?>
            <script>
                window.effectFontSize = '<?php echo esc_js( $font_size ); ?>';
            </script>
            <script src="<?php echo esc_url( EATW_PLUGIN_URL . 'js/effect2.js' ); ?>"></script>
        <?php endif;
    }
}

### 📌 **Summary of Changes:**

– **All URLs** outputted via PHP are wrapped in `esc_url()`.
– **JavaScript inline data** continues using `esc_js()`.
– **HTML/Text** continues using `esc_html()` and `esc_attr()` appropriately.

These changes will fix the security escaping issue flagged by WordPress’s automated scanner.

User
<script>
window.effect1ElementId = '<?php echo esc_js($effect2_id); ?>';
        window.effectFontSize = '<?php echo esc_js($font_size); ?>';
        window.effectTag = '<?php echo esc_js($tag); ?>';
</script>
<script>
" >
</script>
<script>

</script>

';
self::$script_loaded = true;
}
if(!is_admin())
{
?>

<script>
window.effectFontSize = '<?php echo esc_js($font_size); ?>';
</script>
<script>
" >
</script>
Assistant
The specific error you're seeing:

ERROR WordPress.Security.EscapeOutput.OutputNotEscaped found '$effect2_id'

occurs because you're directly outputting a variable (`$effect2_id`) in HTML without escaping it. Even though it's internally generated, WordPress coding standards require explicit escaping.

### ✅ **How to fix the issue:**

Replace this line:

<div class="hero-content" id="<?php echo $effect2_id ?>">

with escaped version:

<div class="hero-content" id="<?php echo esc_attr( $effect2_id ); ?>">

### ✅ **Why use `esc_attr()`?**
– `esc_attr()` safely escapes HTML attributes.
– Required by WordPress coding standards for all dynamic content in attributes.

### ✅ **Corrected snippet:**

Here's your fully corrected snippet for that particular block:

<link rel="stylesheet" href="<?php echo esc_url( EATW_PLUGIN_URL . 'css/effect1.css' ); ?>" />
<?php $effect2_id = 'effect2' . $this->get_id(); ?>
<div class="hero-content" id="<?php echo esc_attr( $effect2_id ); ?>">
    <div class="hero-title">
        <<?php echo esc_html( $tag ); ?> id="titlefont2" class="variable-font-content">
            <?php echo esc_html( $text ); ?>
        </<?php echo esc_html( $tag ); ?>>
    </div>
</div>
<?php 
if ( ! is_admin() ) :
?>
<script>
    window.effect1ElementId = '<?php echo esc_js( $effect2_id ); ?>';
    window.effectFontSize   = '<?php echo esc_js( $font_size ); ?>';
    window.effectTag        = '<?php echo esc_js( $tag ); ?>';
</script>
<script src="<?php echo esc_url( EATW_PLUGIN_URL . 'js/effect1.js' ); ?>"></script>
<?php
endif;

### ✅ **Summary of escaping functions:**
– HTML text content: `esc_html()`
– HTML attribute content: `esc_attr()`
– URLs: `esc_url()`
– JavaScript values: `esc_js()`

Applying these consistently ensures passing WordPress code standards tests.

User
188 14 ERROR WordPress.Security.EscapeOutput.OutputNotEscaped All output should be run through an escaping function (see the Security sections in the WordPress Developer Handbooks), found '$output'.
Assistant
The error:

ERROR WordPress.Security.EscapeOutput.OutputNotEscaped found '$output'

is because you're directly outputting a variable (`$output`) containing HTML attributes and text without explicitly escaping it.

### ✅ **How to fix this issue:**

Instead of directly echoing the whole `$output`, you need to escape each attribute and content individually.

### ✅ **Corrected & Escaped Version:**

Replace this:

$output = "<div id='fit' class='$unique_id fit-container' data-page-id='$current_page_id' data-font-size='{$font_size}'>";
$output .= "<$tag class='$unique_id title variable-font-content'>$text</$tag>";
$output .= "</div>";
echo $output;

with this properly escaped version:

<div id="fit" class="<?php echo esc_attr( $unique_id ); ?> fit-container" data-page-id="<?php echo esc_attr( $current_page_id ); ?>" data-font-size="<?php echo esc_attr( $font_size ); ?>">
    <<?php echo esc_html( $tag ); ?> class="<?php echo esc_attr( $unique_id ); ?> title variable-font-content">
        <?php echo esc_html( $text ); ?>
    </<?php echo esc_html( $tag ); ?>>
</div>

### ✅ **Explanation:**
– Attributes (`id`, `class`, `data-*`) use `esc_attr()`.
– Text content uses `esc_html()`.

This explicitly demonstrates proper escaping, satisfying WordPress coding standards and clearing the error.

### ✅ **Final fixed and secure code:**

Here's how your corrected snippet will look integrated:

<link rel="stylesheet" href="<?php echo esc_url( EATW_PLUGIN_URL . 'css/effect2.css' ); ?>" />
<?php
$unique_id = 'effect-text-' . sprintf( '%02d', $this->get_id() ) . '-page-' . $current_page_id;
?>
<div id="fit" class="<?php echo esc_attr( $unique_id ); ?> fit-container" data-page-id="<?php echo esc_attr( $current_page_id ); ?>" data-font-size="<?php echo esc_attr( $font_size ); ?>">
    <<?php echo esc_html( $tag ); ?> class="<?php echo esc_attr( $unique_id ); ?> title variable-font-content">
        <?php echo esc_html( $text ); ?>
    </<?php echo esc_html( $tag ); ?>>
</div>

Applying this change ensures compliance with WordPress security guidelines and clears the scanning errors.

Leave a Comment

Your email address will not be published. Required fields are marked *