PHP WordPressCustomizationWordCamp Miami 2011Take the Good Parts, Then Bend It To Your WillBy David F. Carrdavid@carrcommunications.com
Self IntroductionFreelance writer, editor, and web consultantWrite for Forbes.com on cloud computing, technology for small to midsize businessesTechnology Editor for WebWeek / Internet World Magazine in1990s, Baseline Magazine 2001-2008Webmaster for small businesses, community organizations, political campaignsWordPress replaced a lot of custom hacksWill mostly be talking about plugins to modify the behavior of the system
OverviewWhy start with WordPress?A Plugin Is Just PHP, a Theme Is PHP/CSSJavaScript / AJAX, tooFiles, system load, and The LoopHooking into Filters and ActionsCustomizing the admin screensCustomizing the front endCreating a custom post typeWhere to learn more
When a Plugin Makes You Popular
Why Start With WordPress?Faster than starting from a clean sheet of paper (blank screen of code)Content management for blogs, web pagesSEO friendlyAvailability of vast array of free themes and plugins, plus commercial optionsLots of tutorial materialStrong developer community
A Plugin Is Just PHP
Anatomy of a ThemeThemes have a similar header in style.css.Theme loads index.php (or page.php, single.php, archive.php) to execute “the loop.” Each also loads header.php, footer.php, and usually sidebar.php
The Loop
Globals and Lookup Functionssite_url()admin_url()content_url() or WP_CONTENT_URLplugins_url() or WP_PLUGIN_URLincludes_url()home_url()WP_PLUGIN_DIRWP_CONTENT_DIRABSPATH – directory including trailing /None of the rest include trailing /So $url = plugins_url() . /demo/report.php
More Globals, Conditional FunctionsNeed to use global keyword at top of function to accessglobal $wpdb – database objectglobal $post$post-ID, $post->post_typeglobal $current_user$current_user->first_nameConditional functionsis_user_logged_in()is_single() or is_single(10)is_page or is_page(10) or is_page('about_us')is_admin() – is this an admin page?
WordPress File HierarchyThe wp-content directory has subdirectories for plugins and themesThe index.php in web root loads the system, loads activatedplugins and themesPlugins: functionalityThemes: look and feelfunctions.php – theme-specific behavior
Hooking Into WordPressCore WordPress API built around 2 kinds of hooks:Filter hooks – intercept some bit of content, modify it, return it. Mostly UI but also some back end filters.A filter on ‘the content’ modifies the content of a post.A filter on ‘posts_orderby’ modifies the ORDER BY clause in the SQL for retrieving posts.Action hooks – triggered by an event in WordPress initialization or loading of template files.The ‘init’ action comes after database is loaded but before page display starts. Can be used to act on a $_POST, then redirect.The ‘wp_header’ and ‘wp_footer’ actions called from header.php and footer.php output custom contentOther actions specific to admin screens, like ‘admin_menu’
Key Actions Public Pagemuplugins_loadedplugins_loadedsetup_themeload_textdomainset_current_userinitwp_loadedparse_requestsend_headersparse_querypre_get_postsposts_selectionwptemplate_redirectwp_headwp_enqueue_scriptswp_print_styleswp_print_scriptsloop_startthe_postloop_endget_sidebarwp_footerwp_print_footer_scriptsshutdown
Sample Filterswp_title (page title)the_title (post title)the_contentthe_content_feedthe_excerptthe_excerpt_rssthe_categorythe_tagsthe_timethe_datethe_weekdaycomment_textcomment_save_prethe_editor_contentwp_list_pagessave_postwp_insert_post_datalogin_redirectcron_schedulesmce_css (rich text editor)posts_requestposts_joinposts_orderbyposts_where
Modifying Admin ScreensThe Default Dashboard
Custom Dashboard
Custom Admin Menus
Function to output menu page
Admin Data Entry Page
Nonce SecurityNumber used onceMake sure requests coming from authenticated user with unique code$nonce= wp_create_nonce ('my-nonce');wp_nonce_field("qday","qnonce") is the same as:<input type=“text” name=“qnonce” value=“<?=$nonce?>”>Test:Code: if(wp_verify_nonce($_POST["qnonce"], "qday") )
Catching $_POST at init / admin-init
Process, Then RedirectSeparate UI from server processingHelps avoid double-submit issuesRedirect with different parameters for success / failureExit after redirectSimilar pattern can be used for AJAX (echo json, then exit)
Wrapper Functions For WP DatabaseCreate a post with code using wp_insert_postRetrieve and change settings using get_option and update_option
Settings API
The WordPress Database
Database Programming with WordPressGlobal $wpdb data access objectGet results with $wpdb->get_resultsGet row with $wpdb->get_rowFormat/quote SQL with $wpdb->prepare
Insert / Update	Remember securityCheck nonceFilter valuesCompensate for “magic quotes” with$postdata = array_map( 'stripslashes_deep', $_POST );Use $wpdb->prepare to quote properlyExecute insert / update with $wpdb->query($sql)
DB Programming PitfallsForgetting to declare $wpdb as globalUse ARRAY_A parameter to get associative array from $wpdb->get_results or $wpdb->get_row if you want results to be accessible as $row["field_name"]Default is object format $row->field_nameUse $wpdb->show_errors() to debug SQLReturn value from $wpdb->query is false on error, or number of rows affected (could be 0)Test for error: if($return_value == false) echo ‘error’;
Allow For Alternate Table NamesDefault table names like wp_posts can have alternate prefixes, so use $wpdb->posts insteadCustom table $wpdb->prefix . "rsvpmaker"
ShortcodesPlaceholder codes site editors can include in pages and postsStandard:[embed] http://www.youtube.com/watch?v=nTDNLUzjkpg[/embed]Custom:[demotag title="Date" date="r"] Date in RFC822 Format [/demotag]
Contact Form ExampleUse a shortcode to display formProcess $_POST on ‘init’ then redirectUse JavaScript jQuery library to enhance
Enqueue Bundled / Custom JavaScriptLoad scripts in right order with wp_enqueue_scriptRegister custom scripts, dependencies with wp_register_script
jQuery and Friends“No Conflict” mode so start with jQuery(document).ready(function($)Warning: Textbook jQuery examples usually start with this shortcut:$(document).ready(function()
Live Example - RSVPMaker
Creating a Custom Post TypeAdd a content type that can use common editing controls but be organized separately
Editing Screen With Custom OptionsStandard formatting / uploading controlsCustom panels: add_meta_boxProcess $_POST on save_post actionSave custom data: update_post_meta
Custom Display for Custom Post TypeFilter ‘the_content’, check post type, look up and format dates for events, display form if is_single() otherwise show RSVP Now! button
SummaryWordPress provides a foundation / frameworkCreate / customize themes to change look and feelDownload or create your own plugins to alter WordPress system behaviorFilters hooks alter content, return resultsAction hooks triggered by initialization stages, function calls in theme templates, administration screen accessCreate your own administration reports / data entry screens.Use wrapper functions and $wpdb global to update DBUse shortcodes, filters, output functions for JavaScript and CSS to enhance public website
Follow UpEmail: david@carrcommunications.comRecommended book:WordPressPlugin Development – Beginner’s Guide by Vladimir PrelovacPresentation/Code/Links:www.carrcommunications.com/wordcamp/www.carrcommunications.com/wordpress-plugins/Developer documentation codex.wordpress.orgForums wordpress.org/support/Mailing lists (wp-hackers etc.) lists.automattic.com

Introduction to Plugin Programming, WordCamp Miami 2011

  • 1.
    PHP WordPressCustomizationWordCamp Miami2011Take the Good Parts, Then Bend It To Your WillBy David F. Carrdavid@carrcommunications.com
  • 2.
    Self IntroductionFreelance writer,editor, and web consultantWrite for Forbes.com on cloud computing, technology for small to midsize businessesTechnology Editor for WebWeek / Internet World Magazine in1990s, Baseline Magazine 2001-2008Webmaster for small businesses, community organizations, political campaignsWordPress replaced a lot of custom hacksWill mostly be talking about plugins to modify the behavior of the system
  • 3.
    OverviewWhy start withWordPress?A Plugin Is Just PHP, a Theme Is PHP/CSSJavaScript / AJAX, tooFiles, system load, and The LoopHooking into Filters and ActionsCustomizing the admin screensCustomizing the front endCreating a custom post typeWhere to learn more
  • 4.
    When a PluginMakes You Popular
  • 5.
    Why Start WithWordPress?Faster than starting from a clean sheet of paper (blank screen of code)Content management for blogs, web pagesSEO friendlyAvailability of vast array of free themes and plugins, plus commercial optionsLots of tutorial materialStrong developer community
  • 6.
    A Plugin IsJust PHP
  • 7.
    Anatomy of aThemeThemes have a similar header in style.css.Theme loads index.php (or page.php, single.php, archive.php) to execute “the loop.” Each also loads header.php, footer.php, and usually sidebar.php
  • 8.
  • 9.
    Globals and LookupFunctionssite_url()admin_url()content_url() or WP_CONTENT_URLplugins_url() or WP_PLUGIN_URLincludes_url()home_url()WP_PLUGIN_DIRWP_CONTENT_DIRABSPATH – directory including trailing /None of the rest include trailing /So $url = plugins_url() . /demo/report.php
  • 10.
    More Globals, ConditionalFunctionsNeed to use global keyword at top of function to accessglobal $wpdb – database objectglobal $post$post-ID, $post->post_typeglobal $current_user$current_user->first_nameConditional functionsis_user_logged_in()is_single() or is_single(10)is_page or is_page(10) or is_page('about_us')is_admin() – is this an admin page?
  • 11.
    WordPress File HierarchyThewp-content directory has subdirectories for plugins and themesThe index.php in web root loads the system, loads activatedplugins and themesPlugins: functionalityThemes: look and feelfunctions.php – theme-specific behavior
  • 12.
    Hooking Into WordPressCoreWordPress API built around 2 kinds of hooks:Filter hooks – intercept some bit of content, modify it, return it. Mostly UI but also some back end filters.A filter on ‘the content’ modifies the content of a post.A filter on ‘posts_orderby’ modifies the ORDER BY clause in the SQL for retrieving posts.Action hooks – triggered by an event in WordPress initialization or loading of template files.The ‘init’ action comes after database is loaded but before page display starts. Can be used to act on a $_POST, then redirect.The ‘wp_header’ and ‘wp_footer’ actions called from header.php and footer.php output custom contentOther actions specific to admin screens, like ‘admin_menu’
  • 13.
    Key Actions PublicPagemuplugins_loadedplugins_loadedsetup_themeload_textdomainset_current_userinitwp_loadedparse_requestsend_headersparse_querypre_get_postsposts_selectionwptemplate_redirectwp_headwp_enqueue_scriptswp_print_styleswp_print_scriptsloop_startthe_postloop_endget_sidebarwp_footerwp_print_footer_scriptsshutdown
  • 14.
    Sample Filterswp_title (pagetitle)the_title (post title)the_contentthe_content_feedthe_excerptthe_excerpt_rssthe_categorythe_tagsthe_timethe_datethe_weekdaycomment_textcomment_save_prethe_editor_contentwp_list_pagessave_postwp_insert_post_datalogin_redirectcron_schedulesmce_css (rich text editor)posts_requestposts_joinposts_orderbyposts_where
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
    Nonce SecurityNumber usedonceMake sure requests coming from authenticated user with unique code$nonce= wp_create_nonce ('my-nonce');wp_nonce_field("qday","qnonce") is the same as:<input type=“text” name=“qnonce” value=“<?=$nonce?>”>Test:Code: if(wp_verify_nonce($_POST["qnonce"], "qday") )
  • 21.
    Catching $_POST atinit / admin-init
  • 22.
    Process, Then RedirectSeparateUI from server processingHelps avoid double-submit issuesRedirect with different parameters for success / failureExit after redirectSimilar pattern can be used for AJAX (echo json, then exit)
  • 23.
    Wrapper Functions ForWP DatabaseCreate a post with code using wp_insert_postRetrieve and change settings using get_option and update_option
  • 24.
  • 25.
  • 26.
    Database Programming withWordPressGlobal $wpdb data access objectGet results with $wpdb->get_resultsGet row with $wpdb->get_rowFormat/quote SQL with $wpdb->prepare
  • 27.
    Insert / Update RemembersecurityCheck nonceFilter valuesCompensate for “magic quotes” with$postdata = array_map( 'stripslashes_deep', $_POST );Use $wpdb->prepare to quote properlyExecute insert / update with $wpdb->query($sql)
  • 28.
    DB Programming PitfallsForgettingto declare $wpdb as globalUse ARRAY_A parameter to get associative array from $wpdb->get_results or $wpdb->get_row if you want results to be accessible as $row["field_name"]Default is object format $row->field_nameUse $wpdb->show_errors() to debug SQLReturn value from $wpdb->query is false on error, or number of rows affected (could be 0)Test for error: if($return_value == false) echo ‘error’;
  • 29.
    Allow For AlternateTable NamesDefault table names like wp_posts can have alternate prefixes, so use $wpdb->posts insteadCustom table $wpdb->prefix . "rsvpmaker"
  • 30.
    ShortcodesPlaceholder codes siteeditors can include in pages and postsStandard:[embed] http://www.youtube.com/watch?v=nTDNLUzjkpg[/embed]Custom:[demotag title="Date" date="r"] Date in RFC822 Format [/demotag]
  • 31.
    Contact Form ExampleUsea shortcode to display formProcess $_POST on ‘init’ then redirectUse JavaScript jQuery library to enhance
  • 32.
    Enqueue Bundled /Custom JavaScriptLoad scripts in right order with wp_enqueue_scriptRegister custom scripts, dependencies with wp_register_script
  • 33.
    jQuery and Friends“NoConflict” mode so start with jQuery(document).ready(function($)Warning: Textbook jQuery examples usually start with this shortcut:$(document).ready(function()
  • 34.
  • 35.
    Creating a CustomPost TypeAdd a content type that can use common editing controls but be organized separately
  • 36.
    Editing Screen WithCustom OptionsStandard formatting / uploading controlsCustom panels: add_meta_boxProcess $_POST on save_post actionSave custom data: update_post_meta
  • 37.
    Custom Display forCustom Post TypeFilter ‘the_content’, check post type, look up and format dates for events, display form if is_single() otherwise show RSVP Now! button
  • 38.
    SummaryWordPress provides afoundation / frameworkCreate / customize themes to change look and feelDownload or create your own plugins to alter WordPress system behaviorFilters hooks alter content, return resultsAction hooks triggered by initialization stages, function calls in theme templates, administration screen accessCreate your own administration reports / data entry screens.Use wrapper functions and $wpdb global to update DBUse shortcodes, filters, output functions for JavaScript and CSS to enhance public website
  • 39.
    Follow UpEmail: david@carrcommunications.comRecommendedbook:WordPressPlugin Development – Beginner’s Guide by Vladimir PrelovacPresentation/Code/Links:www.carrcommunications.com/wordcamp/www.carrcommunications.com/wordpress-plugins/Developer documentation codex.wordpress.orgForums wordpress.org/support/Mailing lists (wp-hackers etc.) lists.automattic.com