SlideShare uma empresa Scribd logo
1 de 39
Baixar para ler offline
Plugin Development Demystified




       Yannick Lefebvre (@ylefebvre)
        Wordpress Plugin Developer
Plugin Development Demystified


Topics
●   Introduction                ●   Meta Boxes
●   Plugins Overview            ●   Shortcodes
●   File Structure              ●   Publishing your plugin
●   Actions and Filter Hooks    ●   Recommended
                                    Readings
●   Activation, Deactivation
    and Removal                 ●   Questions
●   Administration Pages
Introduction


●   Migrated from Blogger to Wordpress in April 2004
●   Released first plugin in March 2005 (Link Library)
●   Released 7 Plugins to date




●   http://profiles.wordpress.org/users/jackdewey/
Plugins Overview


●   Allows developers to extend default Wordpress
    capabilities
●   Open plugin architecture present since very first
    versions
●   Plugin API constantly refined and expanded
●   Plugin code size and complexity vary widely from
    one to another
●   Functionality stays in place when theme is changed
●   Can be installed directly from Wordpress admin or
    through a manual upload and activation process
Basic Plugin File Structure


●   Made from one or more php code file(s)
●   Can optionally contain other file types (e.g. images,
    text files, translation files, etc...)
●   Located directly in the wp-contentplugins directory
    or in a sub-directory within the plugins folder
●   Entry point is a .php file that contains a specific
    plugin header at its top
Plugin File Header


<?php
<?php
/*
/*
Plugin Name: My New Google Analytics Plugin
Plugin Name: My New Google Analytics Plugin
Plugin URI: http://yannickcorner.nayanna.biz
Plugin URI: http://yannickcorner.nayanna.biz
Description: New revolutionary GA Plugin
Description: New revolutionary GA Plugin
Version: 1.0
Version: 1.0
Author: Yannick Lefebvre
Author: Yannick Lefebvre
Author URI: http://yannickcorner.nayanna.biz
Author URI: http://yannickcorner.nayanna.biz
License: GPL2
License: GPL2
*/
*/
?>
?>


●   This information registers the plugin with Wordpress
●   Most of this data is visible to users in the Plugins
    admin section
First plugin sighting
Plugin Evaluation Rules


●   Function declared in plugin can be called from
    theme template file or other plugins
●   Function names must be different from Wordpress
    core functions and other plugins

           ●   Entire content is evaluated each time site
               is rendered
           ●   A single error will usually bring down the
               entire site


●   Using a local development environment is much
    safer than developing on live site
Plugin Evaluation Error
Actions and Filter Hooks


●   The power of plugins comes from their ability to
    register custom functions to be called at specific
    points during the execution of Wordpress
●   This process is called hooking
●   Two types of hooks
    ●   Action hooks allow for code to be executed at a specific point
        during the page processing loop
    ●   Filter hooks are called during Wordpress data processing to
        allow plugins to modify, increase or reduce data before it is
        displayed
Assigning an action hook


add_action ( 'hook_name', 'your_function_name', [priority],
add_action ( 'hook_name', 'your_function_name', [priority],
[accepted_args] );
[accepted_args] );
Example
Example
add_action('wp_head', 'newga_header');
add_action('wp_head', 'newga_header');

●   Most hook names can be found in Wordpress
    Codex. Includes description of arguments and hook
    purpose.
●   More complete list is available on third-party sites,
    but these lack additional information
●   A third source is the Wordpress code itself

function wp_head() {
function wp_head() {
    do_action('wp_head');
    do_action('wp_head');
}
}
Full action hook implementation



add_action('wp_head', 'newga_header');
add_action('wp_head', 'newga_header');
function newga_header() { ?>
function newga_header() { ?>
    <script type="text/javascript">
     <script type="text/javascript">
    var gaJsHost = (("https:" == document.location.protocol) ?
     var gaJsHost = (("https:" == document.location.protocol) ?
"https://ssl." : "http://www.");
"https://ssl." : "http://www.");
    document.write(unescape("%3Cscript src='" + gaJsHost + "google-
     document.write(unescape("%3Cscript src='" + gaJsHost + "google-
analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));
analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));
    </script>
     </script>
    <script type="text/javascript">
     <script type="text/javascript">
    try{
     try{
    var pageTracker = _gat._getTracker("UA-xxxxxx-x");
     var pageTracker = _gat._getTracker("UA-xxxxxx-x");
    pageTracker._trackPageview();
     pageTracker._trackPageview();
    } catch(err) {}
     } catch(err) {}
    </script>
     </script>

<? }
<? }


●   Prints script code in page header when wp_head()
    is called in theme template
Typical Action Hooks for WP Page
Assigning a filter hook


add_filter($tag, $function_to_add, [$priority], [$accepted_args]);
add_filter($tag, $function_to_add, [$priority], [$accepted_args]);
Example
Example
add_filter( 'the_content', 'newga_content_filter');
add_filter( 'the_content', 'newga_content_filter');


●   Filters hooks receive data arguments that they can
    modify within their processing function and must
    return data, modified or intact
●   In WP core, filter function are called with one or
    more data parameters. The number of parameters
    needs to be used for accepted_args value

function the_content($more_link_text = null, $stripteaser = 0) {
function the_content($more_link_text = null, $stripteaser = 0) {
    $content = get_the_content($more_link_text, $stripteaser);
     $content = get_the_content($more_link_text, $stripteaser);
    $content = apply_filters('the_content', $content);
     $content = apply_filters('the_content', $content);
    $content = str_replace(']]>', ']]&gt;', $content);
     $content = str_replace(']]>', ']]&gt;', $content);
    echo $content;
     echo $content;
}
}
Full filter hook implementation


add_filter( 'the_content', 'newga_content_filter');
add_filter( 'the_content', 'newga_content_filter');
function newga_content_filter($the_content) {
function newga_content_filter($the_content) {
    // Search through contents for links and add google analytics
    // Search through contents for links and add google analytics
code after hrefs
code after hrefs
    // <a href="http://www.example.com"
    // <a href="http://www.example.com"
onClick="recordOutboundLink(this, 'Outbound Links',
onClick="recordOutboundLink(this, 'Outbound Links',
'example.com');return false;">
'example.com');return false;">
     return $the_content;
     return $the_content;
 }
 }


●    The result of this code would be extra tags and
     details around links in post and page content
Database Read Filters
Storing plugin data


●   Most plugins have options for user configuration
●   There are multiple ways to store custom plugin data
    ●   Wordpress Options: get_option / set_option, single options or
        arrays
    ●   Custom tables in SQL schema
    ●   Config files in plugin directory
Storing plugin data using Wordpress Options


●   update_option( $option_name, $newvalue );
    ●   Creates option if it does not exist. Updates if it does.
    ●   Accepts single variable or array as value


●   get_option( $show, $default );
    ●   Show is name of option
    ●   Default is optional value to be returned if option does not exist


●   Initial option value is usually created in plugin
    activation function
Activation / Deactivation


●   First step in many plugins is to register functions
    that will be called on activation and deactivation

register_activation_hook(__FILE__, 'my_new_plugin_activate');
register_activation_hook(__FILE__, 'my_new_plugin_activate');
register_deactivation_hook(__FILE__, 'my_new_plugin_deactivate');
register_deactivation_hook(__FILE__, 'my_new_plugin_deactivate');



●   The deactivation function should NOT be used to
    delete user data as deactivation might be temporary
Activation Example


register_activation_hook(__FILE__, 'my_new_plugin_activate');
register_activation_hook(__FILE__, 'my_new_plugin_activate');
function my_new_plugin_activate() {
function my_new_plugin_activate() {
    if (get_option('NewGA_Options') === false)
    if (get_option('NewGA_Options') === false)
    {
    {
        $options['gauser'] = '';
        $options['gauser'] = '';
        update_option('NewGA_Options', $options);
        update_option('NewGA_Options', $options);
    }
    }
}
}


●   This code first checks if the options already exists
    and creates new default values if they don't.
Uninstallation Code


●   Uninstallation code should remove all traces of the
    plugin

register_uninstall_hook(__FILE__, 'my_new_plugin_uninstall');
register_uninstall_hook(__FILE__, 'my_new_plugin_uninstall');



●   Can also be implemented as straight PHP file called
    uninstall.php in plugin directory that will execute
    when uninstalled
Administrative Pages


●   Admin page allows users to configure plugin options
●   Register function to get called when the admin
    menu is built

add_action('admin_menu',
add_action('admin_menu',
'my_new_plugin_admin_menu');
'my_new_plugin_admin_menu');
function my_new_plugin_admin_menu() {
function my_new_plugin_admin_menu() {
       global $pagehooktop;
        global $pagehooktop;
       $pagehooktop = add_menu_page( 'New GA
        $pagehooktop = add_menu_page( 'New GA
General Options', 'New GA', 'manage_options',
General Options', 'New GA', 'manage_options',
'new-ga', 'my_new_plugin_show_admin', plugins_url(
'new-ga', 'my_new_plugin_show_admin', plugins_url(
'/icons/NewGA16.png' , __FILE__ ));
'/icons/NewGA16.png' , __FILE__ ));
    }
    }
Administrative Pages


●    Implement admin page rendering function

    function my_new_plugin_show_admin() {
    function my_new_plugin_show_admin() {
        $options = get_option('NewGA_Options');
        $options = get_option('NewGA_Options');
        ?>
        ?>
        <h1>New Google Analytics Plugin</h1>
        <h1>New Google Analytics Plugin</h1>
       <form name="newgaform" method="post" action="">
       <form name="newgaform" method="post" action="">
        GA User ID: <input type="text" name="gauser" value="<?php
        GA User ID: <input type="text" name="gauser" value="<?php
    echo $options['gauser']; ?>"/><br />
    echo $options['gauser']; ?>"/><br />
        <input type="submit" value="Submit" />
        <input type="submit" value="Submit" />
        </form>
        </form>
    <?php }
    <?php }
Administrative Pages


●   Process Post Data

    function my_new_plugin_show_admin() {
    function my_new_plugin_show_admin() {
       if (isset($_POST['gauser']))
       if (isset($_POST['gauser']))
       {
       {
           $options['gauser'] = $_POST['gauser'];
           $options['gauser'] = $_POST['gauser'];
           update_option('NewGA_Options', $options);
           update_option('NewGA_Options', $options);
       }
       }

       $options = get_option('NewGA_Options');
       $options = get_option('NewGA_Options');
       ?>
       ?>
       <h1>New Google Analytics Plugin</h1>
       <h1>New Google Analytics Plugin</h1>
       <form name="newgaform" method="post" action="">
       <form name="newgaform" method="post" action="">
        GA User ID: <input type="text" name="gauser" value="<?php
        GA User ID: <input type="text" name="gauser" value="<?php
    echo $options['gauser']; ?>"/><br />
    echo $options['gauser']; ?>"/><br />
        <input type="submit" value="Submit" />
        <input type="submit" value="Submit" />
        </form>
        </form>
    <?php }
    <?php }
Administrative Pages


●   Add Security

    function my_new_plugin_show_admin() {
    function my_new_plugin_show_admin() {
       if (isset($_POST['gauser']))
       if (isset($_POST['gauser']))
       {
       {
           check_admin_referer('newga');
           check_admin_referer('newga');
           $options['gauser'] = $_POST['gauser'];
           $options['gauser'] = $_POST['gauser'];
           update_option('NewGA_Options', $options);
           update_option('NewGA_Options', $options);
       }
       }
       $options = get_option('NewGA_Options');
       $options = get_option('NewGA_Options');
       ?>
       ?>
       <h1>New Google Analytics Plugin</h1>
       <h1>New Google Analytics Plugin</h1>
        <form name="newgaform" method="post" action="">
        <form name="newgaform" method="post" action="">
        <?php wp_nonce_field('newga'); ?>
        <?php wp_nonce_field('newga'); ?>
        GA User ID: <input type="text" name="gauser" value="<?php
        GA User ID: <input type="text" name="gauser" value="<?php
    echo $options['gauser']; ?>"/><br />
    echo $options['gauser']; ?>"/><br />
        <input type="submit" value="Submit" />
        <input type="submit" value="Submit" />
        </form>
        </form>
    <?php }
    <?php }
Updated Header Code


●   Use option data in header code

function
function   newga_header() {
           newga_header() {
$options
$options   = get_option('NewGA_Options');
           = get_option('NewGA_Options');
?>
?>
     <script type="text/javascript">
     <script type="text/javascript">
     var gaJsHost = (("https:" == document.location.protocol) ?
     var gaJsHost = (("https:" == document.location.protocol) ?
"https://ssl." : "http://www.");
"https://ssl." : "http://www.");
document.write(unescape("%3Cscript src='" + gaJsHost + "google-
document.write(unescape("%3Cscript src='" + gaJsHost + "google-
analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));
analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));
     </script>
     </script>
     <script type="text/javascript">
     <script type="text/javascript">
     try{
     try{
     var pageTracker = _gat._getTracker("<?php echo $options['gauser']; ?
     var pageTracker = _gat._getTracker("<?php echo $options['gauser']; ?
>");
>");
     pageTracker._trackPageview();
     pageTracker._trackPageview();
     } catch(err) {}
     } catch(err) {}
     </script>
     </script>

<?php
<?php
}
}
Meta Boxes


●   Meta Boxes are the 'containers' that group together
    data fields in the default Wordpress admin sections
●   Plugins can use meta boxes in their own admin
    sections or to add custom sections to other parts of
    Wordpress (e.g. Posts Editor, Links Editor, etc...)
Meta Boxes


function my_new_plugin_admin_menu() {
function my_new_plugin_admin_menu() {
    global $pagehooktop;
    global $pagehooktop;
    $pagehooktop = add_menu_page( 'New GA General Options', "New
    $pagehooktop = add_menu_page( 'New GA General Options', "New
GA", 'manage_options', 'new-ga', 'my_new_plugin_show_admin',
GA", 'manage_options', 'new-ga', 'my_new_plugin_show_admin',
plugins_url( '/icons/NewGA16.png' , __FILE__ ));
plugins_url( '/icons/NewGA16.png' , __FILE__ ));
    add_meta_box('newga_general_meta_box', 'General Settings',
    add_meta_box('newga_general_meta_box', 'General Settings',
'my_new_plugin_meta_box', $pagehooktop, 'normal', 'high');
'my_new_plugin_meta_box', $pagehooktop, 'normal', 'high');

    wp_enqueue_script('postbox');
    wp_enqueue_script('postbox');
}
}
Meta Boxes Implementation


●   The original simple form code does get more
    complex when using meta boxes to include all of the
    right styles
●   Original form code:
     <form name="newgaform" method="post" action="">
     <form name="newgaform" method="post" action="">
     <?php wp_nonce_field('newga'); ?>
     <?php wp_nonce_field('newga'); ?>
     GA User ID: <input type="text" name="gauser" value="<?php echo
     GA User ID: <input type="text" name="gauser" value="<?php echo
$options['gauser']; ?>"/><br />
$options['gauser']; ?>"/><br />
     <input type="submit" value="Submit" />
     <input type="submit" value="Submit" />
     </form>
     </form>

●   New form code on following page...
Meta Boxes Implementation


<form name="newgaform" method="post" action="">
<form name="newgaform" method="post" action="">
      <?php wp_nonce_field('newga'); ?>
      <?php wp_nonce_field('newga'); ?>
     <div id="poststuff" class="metabox-holder" style='width: 95%'>
     <div id="poststuff" class="metabox-holder" style='width: 95%'>
           <div id="post-body">
            <div id="post-body">
                 <div id="post-body-content">
                  <div id="post-body-content">
                       <?php
                        <?php
                              if ($_GET['page'] == 'new-ga')
                              if ($_GET['page'] == 'new-ga')
                              {
                              {
                                    global $pagehooktop;
                                    global $pagehooktop;
                                    do_meta_boxes($pagehooktop, 'normal', $data);
                                    do_meta_boxes($pagehooktop, 'normal', $data);
                              }
                              }
                       ?>
                        ?>
                 </div>
                  </div>
           </div>
            </div>
           <br class="clear"/>
            <br class="clear"/>
     </div>
     </div>
     </form>
     </form>
     <script type="text/javascript">
     <script type="text/javascript">
           //<![CDATA[
           //<![CDATA[
           jQuery(document).ready( function($) {
           jQuery(document).ready( function($) {
                 // close postboxes that should be closed
                 // close postboxes that should be closed
                 $('.if-js-closed').removeClass('if-js-closed').addClass('closed');
                 $('.if-js-closed').removeClass('if-js-closed').addClass('closed');
                 // postboxes setup
                 // postboxes setup
                 postboxes.add_postbox_toggles('<?php
                 postboxes.add_postbox_toggles('<?php
                       if ($_GET['page'] == 'new-ga')
                       if ($_GET['page'] == 'new-ga')
                       {
                       {
                             global $pagehooktop;
                             global $pagehooktop;
                             echo $pagehooktop;
                             echo $pagehooktop;
                       }
                       }
                       ?>');
                       ?>');
           });
           });
           //]]>
           //]]>
  Okay, maybe this one is still a bit mystifying :)
  Okay, maybe this one is still a bit mystifying :)
   </script>
   </script>
Meta Boxes Implementation


●    Code to render contents of Meta Box
    function my_new_plugin_meta_box() { ?>
    function my_new_plugin_meta_box() { ?>
        GA User ID: <input type="text" name="gauser" value="<?php
        GA User ID: <input type="text" name="gauser" value="<?php
    echo $options['gauser']; ?>"/><br />
    echo $options['gauser']; ?>"/><br />
        <input type="submit" value="Submit" />
        <input type="submit" value="Submit" />
    <?php }
    <?php }
Adding meta boxes to existing editors


add_meta_box ('linklibrary_meta_box', 'Link Library - Additional
add_meta_box ('linklibrary_meta_box', 'Link Library - Additional
Link Parameters', 'll_link_edit_extra', 'link', 'normal',
Link Parameters', 'll_link_edit_extra', 'link', 'normal',
'high');
'high');
Saving meta box data added to existing editors


●    Action hooks are used to register custom functions
     to save additional meta box data

    add_action('add_link', 'add_link_field');
    add_action('add_link', 'add_link_field');
    add_action('edit_link', 'add_link_field');
    add_action('edit_link', 'add_link_field');
    add_action('delete_link', 'delete_link_field');
    add_action('delete_link', 'delete_link_field');
    function add_link_field($link_id) {
    function add_link_field($link_id) {
        // Save extra link fields
        // Save extra link fields
        // Can be saved to Wordpress options or custom
        // Can be saved to Wordpress options or custom   MySQL tables
                                                         MySQL tables
        // $link_id parameter is ID of new or existing
        // $link_id parameter is ID of new or existing   link
                                                         link
    }
    }
    Function delete_link_field($link_id) {
    Function delete_link_field($link_id) {
        // Delete custom link data from custom MySQL tables
        // Delete custom link data from custom MySQL tables
        // or Wordpress options
        // or Wordpress options
    }
    }
Adding a shortcode


●   Simple codes used in a post or page to insert
    content
    ●   [gallery]
    ●   [gallery id="123" size="medium"]
●   Can also be used to output special code before and
    after content
    ●   [style1]My text block[/style1]
    ●   These are often introduced by themes
    ●   Dangerous to use since they will become regular text if you
        change to a new theme without these codes
●   Consider creating a simple shortcode plugin if you
    repeatedly insert similar code on site
Shortcode Implementation


●    Since shortcodes are found anywhere within posts /
     pages, they must return their output instead of
     displaying it directly

    add_shortcode('youtubevid', 'youtubevid_func');
    add_shortcode('youtubevid', 'youtubevid_func');
    function youtubevid_func($atts) {
    function youtubevid_func($atts) {
            extract(shortcode_atts(array(
            extract(shortcode_atts(array(
                'id'
                'id'
            ), $atts));
            ), $atts));
           $output = '<iframe width="560" height="349"
            $output = '<iframe width="560" height="349"
    src="http://www.youtube.com/embed/' . $id . '" frameborder="0"
    src="http://www.youtube.com/embed/' . $id . '" frameborder="0"
    allowfullscreen></iframe>';
    allowfullscreen></iframe>';
            return $output;
            return $output;
        }
        }



    [youtubevid id='hDV-lgmNQUE']
    [youtubevid id='hDV-lgmNQUE']
Publishing your plugin on Wordpress.org


●   Any Open Source plugin can be published on
    Wordpress.org with a few very easy steps:
    1) Register on Wordpress.org
    2) Submit a plugin name and description
    3) Receive approval within a few days
    4) Create a plugin readme following wordpress.org template
    5) Publish plugin to Wordpress subversion repository
TortoiseSVN User Interface
Recommended Readings


●   Professional Wordpress Plugin
    Development by Brad Williams, Ozh
    Richard and Justin Tadlock, published by
    WROX Press
●   Wordpress Codex
    (codex.wordpress.com)
●   PHP.net
●   StackOverflow.com Programming
    Samples
●   Today's presentation and code samples
    available at:
    ●   http://yannickcorner.nayanna.biz/wcmtl2011
Questions?


       Thank you for attending this talk on
        Plugin Development Demystified




          Contact: ylefebvre@gmail.com
                 Twitter: @ylefebvre
      Blog : http://yannickcorner.nayanna.biz
Plugins: http://profiles.wordpress.org/users/jackdewey/

Mais conteúdo relacionado

Último

A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)Gabriella Davis
 
08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking MenDelhi Call girls
 
IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsEnterprise Knowledge
 
A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024Results
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘RTylerCroy
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Miguel Araújo
 
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...Neo4j
 
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfThe Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfEnterprise Knowledge
 
2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...Martijn de Jong
 
Unblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesUnblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesSinan KOZAK
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonAnna Loughnan Colquhoun
 
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure serviceWhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure servicePooja Nehwal
 
Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024The Digital Insurer
 
Developing An App To Navigate The Roads of Brazil
Developing An App To Navigate The Roads of BrazilDeveloping An App To Navigate The Roads of Brazil
Developing An App To Navigate The Roads of BrazilV3cube
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Scriptwesley chun
 
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Igalia
 
Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slidevu2urc
 
Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101Paola De la Torre
 
Top 5 Benefits OF Using Muvi Live Paywall For Live Streams
Top 5 Benefits OF Using Muvi Live Paywall For Live StreamsTop 5 Benefits OF Using Muvi Live Paywall For Live Streams
Top 5 Benefits OF Using Muvi Live Paywall For Live StreamsRoshan Dwivedi
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc
 

Último (20)

A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)
 
08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men
 
IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI Solutions
 
A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
 
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
 
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfThe Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
 
2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...
 
Unblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesUnblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen Frames
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt Robison
 
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure serviceWhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
 
Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024
 
Developing An App To Navigate The Roads of Brazil
Developing An App To Navigate The Roads of BrazilDeveloping An App To Navigate The Roads of Brazil
Developing An App To Navigate The Roads of Brazil
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Script
 
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
 
Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slide
 
Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101
 
Top 5 Benefits OF Using Muvi Live Paywall For Live Streams
Top 5 Benefits OF Using Muvi Live Paywall For Live StreamsTop 5 Benefits OF Using Muvi Live Paywall For Live Streams
Top 5 Benefits OF Using Muvi Live Paywall For Live Streams
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
 

Destaque

2024 State of Marketing Report – by Hubspot
2024 State of Marketing Report – by Hubspot2024 State of Marketing Report – by Hubspot
2024 State of Marketing Report – by HubspotMarius Sescu
 
Everything You Need To Know About ChatGPT
Everything You Need To Know About ChatGPTEverything You Need To Know About ChatGPT
Everything You Need To Know About ChatGPTExpeed Software
 
Product Design Trends in 2024 | Teenage Engineerings
Product Design Trends in 2024 | Teenage EngineeringsProduct Design Trends in 2024 | Teenage Engineerings
Product Design Trends in 2024 | Teenage EngineeringsPixeldarts
 
How Race, Age and Gender Shape Attitudes Towards Mental Health
How Race, Age and Gender Shape Attitudes Towards Mental HealthHow Race, Age and Gender Shape Attitudes Towards Mental Health
How Race, Age and Gender Shape Attitudes Towards Mental HealthThinkNow
 
AI Trends in Creative Operations 2024 by Artwork Flow.pdf
AI Trends in Creative Operations 2024 by Artwork Flow.pdfAI Trends in Creative Operations 2024 by Artwork Flow.pdf
AI Trends in Creative Operations 2024 by Artwork Flow.pdfmarketingartwork
 
PEPSICO Presentation to CAGNY Conference Feb 2024
PEPSICO Presentation to CAGNY Conference Feb 2024PEPSICO Presentation to CAGNY Conference Feb 2024
PEPSICO Presentation to CAGNY Conference Feb 2024Neil Kimberley
 
Content Methodology: A Best Practices Report (Webinar)
Content Methodology: A Best Practices Report (Webinar)Content Methodology: A Best Practices Report (Webinar)
Content Methodology: A Best Practices Report (Webinar)contently
 
How to Prepare For a Successful Job Search for 2024
How to Prepare For a Successful Job Search for 2024How to Prepare For a Successful Job Search for 2024
How to Prepare For a Successful Job Search for 2024Albert Qian
 
Social Media Marketing Trends 2024 // The Global Indie Insights
Social Media Marketing Trends 2024 // The Global Indie InsightsSocial Media Marketing Trends 2024 // The Global Indie Insights
Social Media Marketing Trends 2024 // The Global Indie InsightsKurio // The Social Media Age(ncy)
 
Trends In Paid Search: Navigating The Digital Landscape In 2024
Trends In Paid Search: Navigating The Digital Landscape In 2024Trends In Paid Search: Navigating The Digital Landscape In 2024
Trends In Paid Search: Navigating The Digital Landscape In 2024Search Engine Journal
 
5 Public speaking tips from TED - Visualized summary
5 Public speaking tips from TED - Visualized summary5 Public speaking tips from TED - Visualized summary
5 Public speaking tips from TED - Visualized summarySpeakerHub
 
ChatGPT and the Future of Work - Clark Boyd
ChatGPT and the Future of Work - Clark Boyd ChatGPT and the Future of Work - Clark Boyd
ChatGPT and the Future of Work - Clark Boyd Clark Boyd
 
Getting into the tech field. what next
Getting into the tech field. what next Getting into the tech field. what next
Getting into the tech field. what next Tessa Mero
 
Google's Just Not That Into You: Understanding Core Updates & Search Intent
Google's Just Not That Into You: Understanding Core Updates & Search IntentGoogle's Just Not That Into You: Understanding Core Updates & Search Intent
Google's Just Not That Into You: Understanding Core Updates & Search IntentLily Ray
 
Time Management & Productivity - Best Practices
Time Management & Productivity -  Best PracticesTime Management & Productivity -  Best Practices
Time Management & Productivity - Best PracticesVit Horky
 
The six step guide to practical project management
The six step guide to practical project managementThe six step guide to practical project management
The six step guide to practical project managementMindGenius
 
Beginners Guide to TikTok for Search - Rachel Pearson - We are Tilt __ Bright...
Beginners Guide to TikTok for Search - Rachel Pearson - We are Tilt __ Bright...Beginners Guide to TikTok for Search - Rachel Pearson - We are Tilt __ Bright...
Beginners Guide to TikTok for Search - Rachel Pearson - We are Tilt __ Bright...RachelPearson36
 

Destaque (20)

2024 State of Marketing Report – by Hubspot
2024 State of Marketing Report – by Hubspot2024 State of Marketing Report – by Hubspot
2024 State of Marketing Report – by Hubspot
 
Everything You Need To Know About ChatGPT
Everything You Need To Know About ChatGPTEverything You Need To Know About ChatGPT
Everything You Need To Know About ChatGPT
 
Product Design Trends in 2024 | Teenage Engineerings
Product Design Trends in 2024 | Teenage EngineeringsProduct Design Trends in 2024 | Teenage Engineerings
Product Design Trends in 2024 | Teenage Engineerings
 
How Race, Age and Gender Shape Attitudes Towards Mental Health
How Race, Age and Gender Shape Attitudes Towards Mental HealthHow Race, Age and Gender Shape Attitudes Towards Mental Health
How Race, Age and Gender Shape Attitudes Towards Mental Health
 
AI Trends in Creative Operations 2024 by Artwork Flow.pdf
AI Trends in Creative Operations 2024 by Artwork Flow.pdfAI Trends in Creative Operations 2024 by Artwork Flow.pdf
AI Trends in Creative Operations 2024 by Artwork Flow.pdf
 
Skeleton Culture Code
Skeleton Culture CodeSkeleton Culture Code
Skeleton Culture Code
 
PEPSICO Presentation to CAGNY Conference Feb 2024
PEPSICO Presentation to CAGNY Conference Feb 2024PEPSICO Presentation to CAGNY Conference Feb 2024
PEPSICO Presentation to CAGNY Conference Feb 2024
 
Content Methodology: A Best Practices Report (Webinar)
Content Methodology: A Best Practices Report (Webinar)Content Methodology: A Best Practices Report (Webinar)
Content Methodology: A Best Practices Report (Webinar)
 
How to Prepare For a Successful Job Search for 2024
How to Prepare For a Successful Job Search for 2024How to Prepare For a Successful Job Search for 2024
How to Prepare For a Successful Job Search for 2024
 
Social Media Marketing Trends 2024 // The Global Indie Insights
Social Media Marketing Trends 2024 // The Global Indie InsightsSocial Media Marketing Trends 2024 // The Global Indie Insights
Social Media Marketing Trends 2024 // The Global Indie Insights
 
Trends In Paid Search: Navigating The Digital Landscape In 2024
Trends In Paid Search: Navigating The Digital Landscape In 2024Trends In Paid Search: Navigating The Digital Landscape In 2024
Trends In Paid Search: Navigating The Digital Landscape In 2024
 
5 Public speaking tips from TED - Visualized summary
5 Public speaking tips from TED - Visualized summary5 Public speaking tips from TED - Visualized summary
5 Public speaking tips from TED - Visualized summary
 
ChatGPT and the Future of Work - Clark Boyd
ChatGPT and the Future of Work - Clark Boyd ChatGPT and the Future of Work - Clark Boyd
ChatGPT and the Future of Work - Clark Boyd
 
Getting into the tech field. what next
Getting into the tech field. what next Getting into the tech field. what next
Getting into the tech field. what next
 
Google's Just Not That Into You: Understanding Core Updates & Search Intent
Google's Just Not That Into You: Understanding Core Updates & Search IntentGoogle's Just Not That Into You: Understanding Core Updates & Search Intent
Google's Just Not That Into You: Understanding Core Updates & Search Intent
 
How to have difficult conversations
How to have difficult conversations How to have difficult conversations
How to have difficult conversations
 
Introduction to Data Science
Introduction to Data ScienceIntroduction to Data Science
Introduction to Data Science
 
Time Management & Productivity - Best Practices
Time Management & Productivity -  Best PracticesTime Management & Productivity -  Best Practices
Time Management & Productivity - Best Practices
 
The six step guide to practical project management
The six step guide to practical project managementThe six step guide to practical project management
The six step guide to practical project management
 
Beginners Guide to TikTok for Search - Rachel Pearson - We are Tilt __ Bright...
Beginners Guide to TikTok for Search - Rachel Pearson - We are Tilt __ Bright...Beginners Guide to TikTok for Search - Rachel Pearson - We are Tilt __ Bright...
Beginners Guide to TikTok for Search - Rachel Pearson - We are Tilt __ Bright...
 

Wordpress Plugin Development Demystified

  • 1. Plugin Development Demystified Yannick Lefebvre (@ylefebvre) Wordpress Plugin Developer
  • 2. Plugin Development Demystified Topics ● Introduction ● Meta Boxes ● Plugins Overview ● Shortcodes ● File Structure ● Publishing your plugin ● Actions and Filter Hooks ● Recommended Readings ● Activation, Deactivation and Removal ● Questions ● Administration Pages
  • 3. Introduction ● Migrated from Blogger to Wordpress in April 2004 ● Released first plugin in March 2005 (Link Library) ● Released 7 Plugins to date ● http://profiles.wordpress.org/users/jackdewey/
  • 4. Plugins Overview ● Allows developers to extend default Wordpress capabilities ● Open plugin architecture present since very first versions ● Plugin API constantly refined and expanded ● Plugin code size and complexity vary widely from one to another ● Functionality stays in place when theme is changed ● Can be installed directly from Wordpress admin or through a manual upload and activation process
  • 5. Basic Plugin File Structure ● Made from one or more php code file(s) ● Can optionally contain other file types (e.g. images, text files, translation files, etc...) ● Located directly in the wp-contentplugins directory or in a sub-directory within the plugins folder ● Entry point is a .php file that contains a specific plugin header at its top
  • 6. Plugin File Header <?php <?php /* /* Plugin Name: My New Google Analytics Plugin Plugin Name: My New Google Analytics Plugin Plugin URI: http://yannickcorner.nayanna.biz Plugin URI: http://yannickcorner.nayanna.biz Description: New revolutionary GA Plugin Description: New revolutionary GA Plugin Version: 1.0 Version: 1.0 Author: Yannick Lefebvre Author: Yannick Lefebvre Author URI: http://yannickcorner.nayanna.biz Author URI: http://yannickcorner.nayanna.biz License: GPL2 License: GPL2 */ */ ?> ?> ● This information registers the plugin with Wordpress ● Most of this data is visible to users in the Plugins admin section
  • 8. Plugin Evaluation Rules ● Function declared in plugin can be called from theme template file or other plugins ● Function names must be different from Wordpress core functions and other plugins ● Entire content is evaluated each time site is rendered ● A single error will usually bring down the entire site ● Using a local development environment is much safer than developing on live site
  • 10. Actions and Filter Hooks ● The power of plugins comes from their ability to register custom functions to be called at specific points during the execution of Wordpress ● This process is called hooking ● Two types of hooks ● Action hooks allow for code to be executed at a specific point during the page processing loop ● Filter hooks are called during Wordpress data processing to allow plugins to modify, increase or reduce data before it is displayed
  • 11. Assigning an action hook add_action ( 'hook_name', 'your_function_name', [priority], add_action ( 'hook_name', 'your_function_name', [priority], [accepted_args] ); [accepted_args] ); Example Example add_action('wp_head', 'newga_header'); add_action('wp_head', 'newga_header'); ● Most hook names can be found in Wordpress Codex. Includes description of arguments and hook purpose. ● More complete list is available on third-party sites, but these lack additional information ● A third source is the Wordpress code itself function wp_head() { function wp_head() { do_action('wp_head'); do_action('wp_head'); } }
  • 12. Full action hook implementation add_action('wp_head', 'newga_header'); add_action('wp_head', 'newga_header'); function newga_header() { ?> function newga_header() { ?> <script type="text/javascript"> <script type="text/javascript"> var gaJsHost = (("https:" == document.location.protocol) ? var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www."); "https://ssl." : "http://www."); document.write(unescape("%3Cscript src='" + gaJsHost + "google- document.write(unescape("%3Cscript src='" + gaJsHost + "google- analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E")); analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E")); </script> </script> <script type="text/javascript"> <script type="text/javascript"> try{ try{ var pageTracker = _gat._getTracker("UA-xxxxxx-x"); var pageTracker = _gat._getTracker("UA-xxxxxx-x"); pageTracker._trackPageview(); pageTracker._trackPageview(); } catch(err) {} } catch(err) {} </script> </script> <? } <? } ● Prints script code in page header when wp_head() is called in theme template
  • 13. Typical Action Hooks for WP Page
  • 14. Assigning a filter hook add_filter($tag, $function_to_add, [$priority], [$accepted_args]); add_filter($tag, $function_to_add, [$priority], [$accepted_args]); Example Example add_filter( 'the_content', 'newga_content_filter'); add_filter( 'the_content', 'newga_content_filter'); ● Filters hooks receive data arguments that they can modify within their processing function and must return data, modified or intact ● In WP core, filter function are called with one or more data parameters. The number of parameters needs to be used for accepted_args value function the_content($more_link_text = null, $stripteaser = 0) { function the_content($more_link_text = null, $stripteaser = 0) { $content = get_the_content($more_link_text, $stripteaser); $content = get_the_content($more_link_text, $stripteaser); $content = apply_filters('the_content', $content); $content = apply_filters('the_content', $content); $content = str_replace(']]>', ']]&gt;', $content); $content = str_replace(']]>', ']]&gt;', $content); echo $content; echo $content; } }
  • 15. Full filter hook implementation add_filter( 'the_content', 'newga_content_filter'); add_filter( 'the_content', 'newga_content_filter'); function newga_content_filter($the_content) { function newga_content_filter($the_content) { // Search through contents for links and add google analytics // Search through contents for links and add google analytics code after hrefs code after hrefs // <a href="http://www.example.com" // <a href="http://www.example.com" onClick="recordOutboundLink(this, 'Outbound Links', onClick="recordOutboundLink(this, 'Outbound Links', 'example.com');return false;"> 'example.com');return false;"> return $the_content; return $the_content; } } ● The result of this code would be extra tags and details around links in post and page content
  • 17. Storing plugin data ● Most plugins have options for user configuration ● There are multiple ways to store custom plugin data ● Wordpress Options: get_option / set_option, single options or arrays ● Custom tables in SQL schema ● Config files in plugin directory
  • 18. Storing plugin data using Wordpress Options ● update_option( $option_name, $newvalue ); ● Creates option if it does not exist. Updates if it does. ● Accepts single variable or array as value ● get_option( $show, $default ); ● Show is name of option ● Default is optional value to be returned if option does not exist ● Initial option value is usually created in plugin activation function
  • 19. Activation / Deactivation ● First step in many plugins is to register functions that will be called on activation and deactivation register_activation_hook(__FILE__, 'my_new_plugin_activate'); register_activation_hook(__FILE__, 'my_new_plugin_activate'); register_deactivation_hook(__FILE__, 'my_new_plugin_deactivate'); register_deactivation_hook(__FILE__, 'my_new_plugin_deactivate'); ● The deactivation function should NOT be used to delete user data as deactivation might be temporary
  • 20. Activation Example register_activation_hook(__FILE__, 'my_new_plugin_activate'); register_activation_hook(__FILE__, 'my_new_plugin_activate'); function my_new_plugin_activate() { function my_new_plugin_activate() { if (get_option('NewGA_Options') === false) if (get_option('NewGA_Options') === false) { { $options['gauser'] = ''; $options['gauser'] = ''; update_option('NewGA_Options', $options); update_option('NewGA_Options', $options); } } } } ● This code first checks if the options already exists and creates new default values if they don't.
  • 21. Uninstallation Code ● Uninstallation code should remove all traces of the plugin register_uninstall_hook(__FILE__, 'my_new_plugin_uninstall'); register_uninstall_hook(__FILE__, 'my_new_plugin_uninstall'); ● Can also be implemented as straight PHP file called uninstall.php in plugin directory that will execute when uninstalled
  • 22. Administrative Pages ● Admin page allows users to configure plugin options ● Register function to get called when the admin menu is built add_action('admin_menu', add_action('admin_menu', 'my_new_plugin_admin_menu'); 'my_new_plugin_admin_menu'); function my_new_plugin_admin_menu() { function my_new_plugin_admin_menu() { global $pagehooktop; global $pagehooktop; $pagehooktop = add_menu_page( 'New GA $pagehooktop = add_menu_page( 'New GA General Options', 'New GA', 'manage_options', General Options', 'New GA', 'manage_options', 'new-ga', 'my_new_plugin_show_admin', plugins_url( 'new-ga', 'my_new_plugin_show_admin', plugins_url( '/icons/NewGA16.png' , __FILE__ )); '/icons/NewGA16.png' , __FILE__ )); } }
  • 23. Administrative Pages ● Implement admin page rendering function function my_new_plugin_show_admin() { function my_new_plugin_show_admin() { $options = get_option('NewGA_Options'); $options = get_option('NewGA_Options'); ?> ?> <h1>New Google Analytics Plugin</h1> <h1>New Google Analytics Plugin</h1> <form name="newgaform" method="post" action=""> <form name="newgaform" method="post" action=""> GA User ID: <input type="text" name="gauser" value="<?php GA User ID: <input type="text" name="gauser" value="<?php echo $options['gauser']; ?>"/><br /> echo $options['gauser']; ?>"/><br /> <input type="submit" value="Submit" /> <input type="submit" value="Submit" /> </form> </form> <?php } <?php }
  • 24. Administrative Pages ● Process Post Data function my_new_plugin_show_admin() { function my_new_plugin_show_admin() { if (isset($_POST['gauser'])) if (isset($_POST['gauser'])) { { $options['gauser'] = $_POST['gauser']; $options['gauser'] = $_POST['gauser']; update_option('NewGA_Options', $options); update_option('NewGA_Options', $options); } } $options = get_option('NewGA_Options'); $options = get_option('NewGA_Options'); ?> ?> <h1>New Google Analytics Plugin</h1> <h1>New Google Analytics Plugin</h1> <form name="newgaform" method="post" action=""> <form name="newgaform" method="post" action=""> GA User ID: <input type="text" name="gauser" value="<?php GA User ID: <input type="text" name="gauser" value="<?php echo $options['gauser']; ?>"/><br /> echo $options['gauser']; ?>"/><br /> <input type="submit" value="Submit" /> <input type="submit" value="Submit" /> </form> </form> <?php } <?php }
  • 25. Administrative Pages ● Add Security function my_new_plugin_show_admin() { function my_new_plugin_show_admin() { if (isset($_POST['gauser'])) if (isset($_POST['gauser'])) { { check_admin_referer('newga'); check_admin_referer('newga'); $options['gauser'] = $_POST['gauser']; $options['gauser'] = $_POST['gauser']; update_option('NewGA_Options', $options); update_option('NewGA_Options', $options); } } $options = get_option('NewGA_Options'); $options = get_option('NewGA_Options'); ?> ?> <h1>New Google Analytics Plugin</h1> <h1>New Google Analytics Plugin</h1> <form name="newgaform" method="post" action=""> <form name="newgaform" method="post" action=""> <?php wp_nonce_field('newga'); ?> <?php wp_nonce_field('newga'); ?> GA User ID: <input type="text" name="gauser" value="<?php GA User ID: <input type="text" name="gauser" value="<?php echo $options['gauser']; ?>"/><br /> echo $options['gauser']; ?>"/><br /> <input type="submit" value="Submit" /> <input type="submit" value="Submit" /> </form> </form> <?php } <?php }
  • 26. Updated Header Code ● Use option data in header code function function newga_header() { newga_header() { $options $options = get_option('NewGA_Options'); = get_option('NewGA_Options'); ?> ?> <script type="text/javascript"> <script type="text/javascript"> var gaJsHost = (("https:" == document.location.protocol) ? var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www."); "https://ssl." : "http://www."); document.write(unescape("%3Cscript src='" + gaJsHost + "google- document.write(unescape("%3Cscript src='" + gaJsHost + "google- analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E")); analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E")); </script> </script> <script type="text/javascript"> <script type="text/javascript"> try{ try{ var pageTracker = _gat._getTracker("<?php echo $options['gauser']; ? var pageTracker = _gat._getTracker("<?php echo $options['gauser']; ? >"); >"); pageTracker._trackPageview(); pageTracker._trackPageview(); } catch(err) {} } catch(err) {} </script> </script> <?php <?php } }
  • 27. Meta Boxes ● Meta Boxes are the 'containers' that group together data fields in the default Wordpress admin sections ● Plugins can use meta boxes in their own admin sections or to add custom sections to other parts of Wordpress (e.g. Posts Editor, Links Editor, etc...)
  • 28. Meta Boxes function my_new_plugin_admin_menu() { function my_new_plugin_admin_menu() { global $pagehooktop; global $pagehooktop; $pagehooktop = add_menu_page( 'New GA General Options', "New $pagehooktop = add_menu_page( 'New GA General Options', "New GA", 'manage_options', 'new-ga', 'my_new_plugin_show_admin', GA", 'manage_options', 'new-ga', 'my_new_plugin_show_admin', plugins_url( '/icons/NewGA16.png' , __FILE__ )); plugins_url( '/icons/NewGA16.png' , __FILE__ )); add_meta_box('newga_general_meta_box', 'General Settings', add_meta_box('newga_general_meta_box', 'General Settings', 'my_new_plugin_meta_box', $pagehooktop, 'normal', 'high'); 'my_new_plugin_meta_box', $pagehooktop, 'normal', 'high'); wp_enqueue_script('postbox'); wp_enqueue_script('postbox'); } }
  • 29. Meta Boxes Implementation ● The original simple form code does get more complex when using meta boxes to include all of the right styles ● Original form code: <form name="newgaform" method="post" action=""> <form name="newgaform" method="post" action=""> <?php wp_nonce_field('newga'); ?> <?php wp_nonce_field('newga'); ?> GA User ID: <input type="text" name="gauser" value="<?php echo GA User ID: <input type="text" name="gauser" value="<?php echo $options['gauser']; ?>"/><br /> $options['gauser']; ?>"/><br /> <input type="submit" value="Submit" /> <input type="submit" value="Submit" /> </form> </form> ● New form code on following page...
  • 30. Meta Boxes Implementation <form name="newgaform" method="post" action=""> <form name="newgaform" method="post" action=""> <?php wp_nonce_field('newga'); ?> <?php wp_nonce_field('newga'); ?> <div id="poststuff" class="metabox-holder" style='width: 95%'> <div id="poststuff" class="metabox-holder" style='width: 95%'> <div id="post-body"> <div id="post-body"> <div id="post-body-content"> <div id="post-body-content"> <?php <?php if ($_GET['page'] == 'new-ga') if ($_GET['page'] == 'new-ga') { { global $pagehooktop; global $pagehooktop; do_meta_boxes($pagehooktop, 'normal', $data); do_meta_boxes($pagehooktop, 'normal', $data); } } ?> ?> </div> </div> </div> </div> <br class="clear"/> <br class="clear"/> </div> </div> </form> </form> <script type="text/javascript"> <script type="text/javascript"> //<![CDATA[ //<![CDATA[ jQuery(document).ready( function($) { jQuery(document).ready( function($) { // close postboxes that should be closed // close postboxes that should be closed $('.if-js-closed').removeClass('if-js-closed').addClass('closed'); $('.if-js-closed').removeClass('if-js-closed').addClass('closed'); // postboxes setup // postboxes setup postboxes.add_postbox_toggles('<?php postboxes.add_postbox_toggles('<?php if ($_GET['page'] == 'new-ga') if ($_GET['page'] == 'new-ga') { { global $pagehooktop; global $pagehooktop; echo $pagehooktop; echo $pagehooktop; } } ?>'); ?>'); }); }); //]]> //]]> Okay, maybe this one is still a bit mystifying :) Okay, maybe this one is still a bit mystifying :) </script> </script>
  • 31. Meta Boxes Implementation ● Code to render contents of Meta Box function my_new_plugin_meta_box() { ?> function my_new_plugin_meta_box() { ?> GA User ID: <input type="text" name="gauser" value="<?php GA User ID: <input type="text" name="gauser" value="<?php echo $options['gauser']; ?>"/><br /> echo $options['gauser']; ?>"/><br /> <input type="submit" value="Submit" /> <input type="submit" value="Submit" /> <?php } <?php }
  • 32. Adding meta boxes to existing editors add_meta_box ('linklibrary_meta_box', 'Link Library - Additional add_meta_box ('linklibrary_meta_box', 'Link Library - Additional Link Parameters', 'll_link_edit_extra', 'link', 'normal', Link Parameters', 'll_link_edit_extra', 'link', 'normal', 'high'); 'high');
  • 33. Saving meta box data added to existing editors ● Action hooks are used to register custom functions to save additional meta box data add_action('add_link', 'add_link_field'); add_action('add_link', 'add_link_field'); add_action('edit_link', 'add_link_field'); add_action('edit_link', 'add_link_field'); add_action('delete_link', 'delete_link_field'); add_action('delete_link', 'delete_link_field'); function add_link_field($link_id) { function add_link_field($link_id) { // Save extra link fields // Save extra link fields // Can be saved to Wordpress options or custom // Can be saved to Wordpress options or custom MySQL tables MySQL tables // $link_id parameter is ID of new or existing // $link_id parameter is ID of new or existing link link } } Function delete_link_field($link_id) { Function delete_link_field($link_id) { // Delete custom link data from custom MySQL tables // Delete custom link data from custom MySQL tables // or Wordpress options // or Wordpress options } }
  • 34. Adding a shortcode ● Simple codes used in a post or page to insert content ● [gallery] ● [gallery id="123" size="medium"] ● Can also be used to output special code before and after content ● [style1]My text block[/style1] ● These are often introduced by themes ● Dangerous to use since they will become regular text if you change to a new theme without these codes ● Consider creating a simple shortcode plugin if you repeatedly insert similar code on site
  • 35. Shortcode Implementation ● Since shortcodes are found anywhere within posts / pages, they must return their output instead of displaying it directly add_shortcode('youtubevid', 'youtubevid_func'); add_shortcode('youtubevid', 'youtubevid_func'); function youtubevid_func($atts) { function youtubevid_func($atts) { extract(shortcode_atts(array( extract(shortcode_atts(array( 'id' 'id' ), $atts)); ), $atts)); $output = '<iframe width="560" height="349" $output = '<iframe width="560" height="349" src="http://www.youtube.com/embed/' . $id . '" frameborder="0" src="http://www.youtube.com/embed/' . $id . '" frameborder="0" allowfullscreen></iframe>'; allowfullscreen></iframe>'; return $output; return $output; } } [youtubevid id='hDV-lgmNQUE'] [youtubevid id='hDV-lgmNQUE']
  • 36. Publishing your plugin on Wordpress.org ● Any Open Source plugin can be published on Wordpress.org with a few very easy steps: 1) Register on Wordpress.org 2) Submit a plugin name and description 3) Receive approval within a few days 4) Create a plugin readme following wordpress.org template 5) Publish plugin to Wordpress subversion repository
  • 38. Recommended Readings ● Professional Wordpress Plugin Development by Brad Williams, Ozh Richard and Justin Tadlock, published by WROX Press ● Wordpress Codex (codex.wordpress.com) ● PHP.net ● StackOverflow.com Programming Samples ● Today's presentation and code samples available at: ● http://yannickcorner.nayanna.biz/wcmtl2011
  • 39. Questions? Thank you for attending this talk on Plugin Development Demystified Contact: ylefebvre@gmail.com Twitter: @ylefebvre Blog : http://yannickcorner.nayanna.biz Plugins: http://profiles.wordpress.org/users/jackdewey/