Developer's Roundtable Notes

Session: Creating a Plugin

Why Do You Want a Plugin?

Before deciding how to enhance your site, ask yourself these questions:

What’s the specific functionality you need?

Is there a core function already in place for this?

Is it a simple, single function like adding another sidebar or customizing the admin menu?

Do you (or your client) need to change options for this particular use?

 


 

This will help you decide if it’s more effective to install a third party plugin, or if you should write one yourself.

And, when weighing your time, remember to include how long it will take you to find, test, and vet someone else’s plugin.

Also remember that once you’ve written a plugin, you can easily modify and re-use it for other projects.

 

Do It Yourself Advantages

You only have the features you specifically need – no bloat

You can reduce database calls (and page load speed) by hard coding options

If there’s an issue or a conflict, you know where to find it

Once you’ve written it, you can use it over and over – just like any other plugin

An Example of DIY Savings

Scenario: Client wants to add various PayPal buttons throughout the site.

Solution 1:

Teach your client to create buttons in Paypal, find and copy the code into the text editor – every time they want to add a button.

Solution 2:

Find a plugin that creates a shortcode (this one makes 4 database calls to get options I know my client doesn’t need)

<?php

if( ! array_key_exists( 'swer-paypal-shortcodes', $GLOBALS ) ) { 
    class SWER_paypal_shortcodes{

        function __construct(){
            add_shortcode('paypal', array( $this, 'swer_paypal_shortcode') );
            add_action( 'admin_init', array( &$this, '_admin_init' ) );
        }

        function _admin_init(){
            add_settings_section( 'swer_paypal_shortcode', 'PayPal Shortcode', array( &$this, 'options_header'), 'writing');

            add_settings_field( 'swer_paypal_email', 'Email', array( &$this, 'options_paypal_email'), 'writing', 'swer_paypal_shortcode');
            register_setting( 'writing', 'swer_paypal_email' );

            add_settings_field( 'swer_paypal_currency', 'Currency', array( &$this, 'options_paypal_currency'), 'writing', 'swer_paypal_shortcode');
            register_setting( 'writing', 'swer_paypal_currency' );
            
            add_settings_field( 'swer_paypal_text_add', 'ADD Text', array( &$this, 'options_paypal_text_add'), 'writing', 'swer_paypal_shortcode');
            register_setting( 'writing', 'swer_paypal_text_add' );

            add_settings_field( 'swer_paypal_text_view', 'VIEW Text', array( &$this, 'options_paypal_text_view'), 'writing', 'swer_paypal_shortcode');
            register_setting( 'writing', 'swer_paypal_text_view' );
        }


        function options_header(){
            echo 'Add Item: <code>[paypal type="add" name="Item Name" amount="12.99"]</code>. View Items: <code>[paypal type="view"]</code>';
        }


        function options_paypal_email(){
            $mail = get_option( 'swer_paypal_email' );
            $value = ($mail!='') ? $mail : '';
            echo '<input type="text" name="swer_paypal_email" id="swer_paypal_email" value="'.$value.'"/>';
        }

        function options_paypal_currency(){
            $mail = get_option( 'swer_paypal_currency' );
            $value = ($mail!='') ? $mail : '';
            echo '<input type="text" name="swer_paypal_currency" id="swer_paypal_currency" value="'.$value.'"/>';
        }

        function options_paypal_text_add(){
            $text = get_option( 'swer_paypal_text_add' );
            $value = ( $text!=='' ) ? $text : '';
            echo '<input type="text" name="swer_paypal_text_add" id="swer_paypal_text_add" value="'.$value.'"/>';
        }

        function options_paypal_text_view(){
            $text = get_option( 'swer_paypal_text_view' );
            $value = ( $text!=='' ) ? $text : '';
            echo '<input type="text" name="swer_paypal_text_view" id="swer_paypal_text_view" value="'.$value.'"/>';
        }



     
        // [paypal type="add" name="Item Name" amount="12.99"]
        // [paypal type="view"]
        function swer_paypal_shortcode($atts) {

            extract( shortcode_atts( array(
               'type' => 'paynow',
               'name' => '',
               'amount' => ''
               ), $atts ) );


        switch( $type ):

        	case "add":	
        	case "paynow":
        	$code = '
                <form name="paypal-cart" action="https://www.paypal.com/cgi-bin/webscr" method="post">
                <input type="hidden" name="cmd" value="_xclick" />
        		<input type="hidden" name="business" value="'.get_option('swer_paypal_email',true).'">
        		<input type="hidden" name="currency_code" value="'.get_option('swer_paypal_currency',true).'">
        		<input type="hidden" name="item_name" value="'.$name.'">
        		<input type="hidden" name="amount" value="'.$amount.'">

                <input type="hidden" name="no_shipping" value="2" />
                <input type="hidden" name="no_note" value="1" />
                <input type="hidden" name="bn" value="IC_Sample" />

        		<input type="image" src="https://www.paypal.com/en_US/i/btn/btn_paynowCC_LG.gif" border="0" name="submit" alt="'.get_option('swer_paypal_text_add',true).'">
        		<input type="hidden" name="add" value="1">
        		</form>';
        	break;

        	case "view":
        	$code = '
        		<form name="_xclick" target="paypal" action="https://www.paypal.com/cgi-bin/webscr" method="post">
        		<input type="hidden" name="cmd" value="_cart">
        		<input type="hidden" name="business" value="'.get_option('swer_paypal_email',true).'">
        		<input type="image" src="https://www.paypal.com/en_US/i/btn/view_cart_new.gif" border="0" name="submit" alt="'.get_option('swer_paypal_text_view',true).'">
        		<input type="hidden" name="display" value="1">
        		</form>
        	';
        	break;	
        endswitch;
        return $code;	
        }
     
        
    }
    $GLOBALS['swer-paypal-shortcodes'] = new SWER_paypal_shortcodes();
}

 

Solution 3:

Write a plugin that creates a shortcode

<?php
/**
 * Plugin Name: PayPal Button Shortcode
 * Description: PayPal Buy Now button plugin with shortcode.
 * Version: 1.0
 * Author: Diana Nichols
 * Author URI: http://www.lavenderthreads.com
 */

function paypal_shortcode( $atts ) {

extract( shortcode_atts( 
	array( 
		'amount' => '50', 
		'name' => 'Payment to MyCompany' 
		), 
		$atts 
	));

return '<form action="https://www.paypal.com/cgi-bin/webscr" method="post">
                <div class="paypal-donations">
                    <input type="hidden" name="cmd" value="_xclick">
                    <input type="hidden" name="business" value="email@mydomain.com">
                    <input type="hidden" name="amount" value="' . $amount. '">
					<input type="hidden" name="item_name" value="'.$name.'">
                    <input type="hidden" name="rm" value="0">
                    <input type="hidden" name="currency_code" value="USD">
                    <input type="image" src="https://www.paypal.com/en_US/i/btn/btn_buynow_sm.gif" name="submit" alt="PayPal - The safer, easier way to pay online">
                    <img alt="" src="https://www.paypal.com/en_US/i/scr/pixel.gif" width="1" height="1">
                </div>
            </form>';
}
add_shortcode( 'ppbutton', 'paypal_shortcode' );

 

Client simply adds a shortcode every time they want a new button:

[ppbutton name="my product" amount="100"]

 

Some Easy DIY Plugins

  1. Custom Post Types
    • FAQs
    • Testimonials
    • Staff Members
  2. Share buttons
  3. Custom Login Logo
  4. Breadcrumbs

You’ve Decided to Do It Yourself

So, your next decision is whether to place your function in functions.php, or build a plugin.

From the client’s perspective

 

Does the function and the data need to survive a theme change?

 

No – functions.php

Yes – plugin

 


 

I always assume that at some point the client will want a new theme – or may hire another developer.

It’s just good practice to allow for that.

Some themes put site content into custom post types or content blocks created inside the theme. Not a best practice, in my book.

 

Some Examples

functions.php

plugin

theme features
sidebars
menus
widgetized areas
changes to <head>
custom excerpt lengths
anything that affects presentation of content

custom post types
shortcodes
analytics
dashboard customization
added avatar
custom profile fields

 

it depends

custom image sizes
scripts & styles
custom login styles

 


 

One more note: When I’m trying something I’m not completely sure about, even if it should go into the functions file, I put it in a plugin. Then, if it crashes, the whole site doesn’t go down, and I can just uninstall the plugin.

Let’s Create a Plugin

Following are three functions that could be placed in either a functions file, or a plugin, depending on the project and the client.

For my purposes here, I’ve chosen to include them in a plugin.

Add a Read More Tag to the End of Excerpts

Replace that confusing […] with a read more button.

 

function lt_new_excerpt_more($more) {
   global $post;
   return '<br><a class="moretag" href="'. get_permalink($post->ID) . '"> [Read More...]</a>';
}
add_filter('excerpt_more', 'lt_new_excerpt_more');

 

 

Remove Query Strings from Script URLs

// copied from https://wordpress.org/plugins/remove-query-strings-from-static-resources/  
function lt_remove_query_strings_1( $src ) {
	$rqs = explode( '?ver', $src );
    return $rqs[0];
}
function lt_remove_query_strings_2( $src ) {
	$rqs = explode( '&ver', $src );
    return $rqs[0];
}
add_filter( 'script_loader_src', 'lt_remove_query_strings_1', 15, 1 );
add_filter( 'style_loader_src', 'lt_remove_query_strings_1', 15, 1 );
add_filter( 'script_loader_src', 'lt_remove_query_strings_2', 15, 1 );
add_filter( 'style_loader_src', 'lt_remove_query_strings_2', 15, 1 );

For load speed and clean URLs

Add a Custom Default Avatar Image

 

function lt_add_avatar( $avatar_defaults ) {
    $myavatar = 'path-to-my-image/avatar.jpg';
    $avatar_defaults[$myavatar] = 'New Avatar';
    return $avatar_defaults;
}
add_filter( 'avatar_defaults', ‘lt_add_avatar' );

Upload the image to the media library. If you upload it to my-theme/images/ it will be lost with a new theme.

By default, avatars are 32px x 32px. If you want them larger, size your image accordingly.

Make the Plugin

1. Make a PHP file

2. Add the plugin header

<?php
/**
 * Plugin Name: MySite.com Functions 
 * Description: Some functions for MySite.com: redirect non-admin users to the front end, add read more links, remove version query strings from URLs
 * Author: Diana Nichols
 * Author URI: http://LavenderThreads.com
 */

3. Add your functions

4. Create a new folder in plugins directory

5. Upload the file (name it anything you like)

6. Activate

The New Plugin

<?php
/**
 * Plugin Name: MySite.com Functions 
 * Description: Some functions for MySite.com: redirect non-admin users to the front end, add read more links, remove version query strings from URLs
 * Author: Diana Nichols
 * Author URI: http://LavenderThreads.com
 */

//custom avatar
function dw_addgravatar( $avatar_defaults ) {
    $myavatar = content_url() . '/uploads/avatar.jpg';
    $avatar_defaults[$myavatar] = 'New Avatar';
    return $avatar_defaults;
    }
add_filter( 'avatar_defaults', 'dw_addgravatar' );


// Puts link in excerpts more tag
function lt_new_excerpt_more($more) {
    global $post;
    return '<br><a class="moretag" href="'. get_permalink($post->ID) . '"> [Read More...]</a>';
}
add_filter('excerpt_more', 'lt_new_excerpt_more');


//remove query strings from script urls (for load speed)
//this function was copied from https://wordpress.org/plugins/remove-query-strings-from-static-resources/ 
function lt_remove_query_strings_1( $src ) {
	$rqs = explode( '?ver', $src );
    return $rqs[0];
}
function lt_remove_query_strings_2( $src ) {
	$rqs = explode( '&ver', $src );
    return $rqs[0];
}
add_filter( 'script_loader_src', 'lt_remove_query_strings_1', 15, 1 );
add_filter( 'style_loader_src', 'lt_remove_query_strings_1', 15, 1 );
add_filter( 'script_loader_src', 'lt_remove_query_strings_2', 15, 1 );
add_filter( 'style_loader_src', ';t_remove_query_strings_2', 15, 1 );

 

Plugin Tip

To “hide” essential plugins so they don’t get de-activated accidentally:

Put your plugin.php file (not the whole folder) into a directory called “mu-plugins”.

 

 

Skip to toolbar