Created my first wordpress plugin template page, need comments I managed to create my first wordpress plugin template page collecting various code snippets to make the page function.

Everything works fine, but I need hear comments from PHP &amp; wordpress experts to see if it's well-coded.

Here's the code.

&lt;?php
/*
Plugin Name: name
Plugin URI: http://www.example.com
Description: desc
Version: 1
Author: someone
Author URI: http://www.example
*/
?&gt;
&lt;?php
function my_first_plugin_init(){
    register_setting( 'my_first_plugin_grp', 'my_first_plugin' );
}
add_action( 'admin_init', 'my_first_plugin_init' );

function my_first_plugin_add_page() {
    add_menu_page('plugin title', 'plugin title', 'manage_options', 'my_first_plugin', 'my_first_plugin_do_page' );
}
add_action( 'admin_menu', 'my_first_plugin_add_page' );

function my_first_plugin_scripts() {
    wp_enqueue_script('media-upload');
    wp_enqueue_script('thickbox');
    wp_enqueue_script('my-upload', plugin_dir_url( __FILE__ ).'/upload-func.js');
}
add_action('admin_print_scripts', 'my_first_plugin_scripts');

function my_first_plugin_styles() {
    wp_enqueue_style('ads-stls', plugin_dir_url( __FILE__ ).'/ads-options.css');
    wp_enqueue_style('thickbox');
}
add_action('admin_print_styles', 'my_first_plugin_styles');

function my_first_plugin_do_page() {
    global $select_options, $radio_options;
    if ( ! isset( $_REQUEST['settings-updated'] ) )
    $_REQUEST['settings-updated'] = false;
?&gt;
&lt;div class="wrap"&gt;
    &lt;h2&gt;&lt;?php echo $plgnme; ?&gt;&lt;/h2&gt;
    &lt;?php if ( false !== $_REQUEST['settings-updated'] ) : ?&gt;
    &lt;div class="updated fade"&gt;&lt;p&gt;&lt;strong&gt;Options saved.&lt;/strong&gt;&lt;/p&gt;&lt;/div&gt;
    &lt;?php endif; ?&gt;
    &lt;form method="post" action="options.php"&gt;
    &lt;?php settings_fields( 'my_first_plugin_grp' ); ?&gt;
    &lt;?php $options = get_option( 'my_first_plugin' ); ?&gt;    
&lt;!-- content start --&gt;
&lt;!-- ///////////////////////////////////////////////////////////////////////////////////////////////////// --&gt;
Sample text input:
&lt;input id="my_first_plugin[lpgrdneurl]" class="regular-text" type="text" name="my_first_plugin[lpgrdneurl]" value="&lt;?php esc_attr_e( $options[$lpgrdneurl] ); ?&gt;" placeholder="http://" /&gt;
&lt;!-- ///////////////////////////////////////////////////////////////////////////////////////////////////// --&gt;
&lt;!-- content end --&gt;
    &lt;?php submit_button(); ?&gt;
    &lt;/form&gt;
&lt;/div&gt;
&lt;div class="clear"&gt;&lt;/div&gt;
&lt;?php } ?&gt;
First of all, your plugin is not translation ready, see l18n. In the plugin header, you should add

* Text Domain: your-textdomain
* Domain Path: /languages


Create the language files in wp-content/plugins/your-plugin/languages with PoEdit. And make all relevant strings translatable with:

add_menu_page( __('Plugin title','your-textdomain'), ...
// and
&lt;?php _e('Options saved','your-textdomain'); ?&gt;




There's a big issue: you're printing your styles and scripts all over the admin area. It's essential that you always target the correct page.

add_action( 'admin_menu', 'my_first_plugin_add_page' );
function my_first_plugin_add_page() 
{
    $hook = add_menu_page(
        'plugin title', 
        'plugin title', 
        'manage_options', 
        'my_first_plugin', 
        'my_first_plugin_do_page'
    );
    add_action( "admin_print_scripts-$hook", 'my_first_plugin_scripts' );   
}




You don't need to close and open PHP tags if you're not swapping between PHP and HTML:

*/
?&gt;
&lt;?php
function my_first_plugin_init(){


Get rid of the very last ?&gt; too.
See Why do some scripts omit the closing php tag ?&gt;.



It's easier to have a general picture if you declare first the hooks and then the callbacks.

add_action('first_hook', 'prefix_first_callback');
add_action('second_hook', 'prefix_second_callback');
add_filter('third_hook', 'prefix_third_callback');
function prefix_first_callback() {}
function prefix_second_callback() {}
function prefix_third_callback() {}




It's important to prefix everything, function names, meta data and $_POSTed data. But for function names this quickly turns into hard to read code. Encapsulating everything in a class avoids this. And also allows us to start-up our plugin in a safe point: plugins_loaded, see Best way to initiate a class in a WP plugin?.

The following is a clean version of Plugin Class Demo, by toscho◆. Please, go to the source for the full documented class.

add_action(
    'plugins_loaded',
    array ( PREFIX_My_Plugin::get_instance(), 'plugin_setup' )
);

class PREFIX_My_Plugin
{
    protected static $instance = NULL;
    public $plugin_url = '';
    public $plugin_path = '';

    public static function get_instance()
    {
        NULL === self::$instance and self::$instance = new self;
        return self::$instance;
    }

    public function plugin_setup()
    {
        $this-&gt;plugin_url    = plugins_url( '/', __FILE__ );
        $this-&gt;plugin_path   = plugin_dir_path( __FILE__ );
        $this-&gt;load_language( 'plugin_unique_name' );
        // Your stuff: register actions and filters
        add_action( 'admin_init', array( $this, '_admin_init' ) );
    }

    public function _admin_init()
    {
        // your_stuff();
    }

    public function __construct() {}

    public function load_language( $domain )
    {
        load_plugin_textdomain(
            $domain,
            FALSE,
            $this-&gt;plugin_path . 'languages'
        );
    }
}