Plugging intoMatt Harris
<head> conference26th October 2008
1
Type
s of
Wor
dpre
ss Wordpress.comHosted blogging solution
Wordpress.orgDownloadable edition for use on your own server
Wordpress MUMulti-user edition of Wordpress.org
2
Wor
dpre
ss.c
omHosted
Free
Maintained and backed up for you
Not hackable or pluggable by you
3Hosted: scalable, Automa1c deals with the spikes you may get
Wor
dpre
ss.o
rgCustomisable
Self-hosted
Complete code control
Maintenance, backup and reliability are your responsibility
4Customisable: hackable, expandable. Add your own features
Wor
dpre
ss M
UAll of Wordpress.org pros and cons
Hosting of multiple blogs under one install
Bespoke permission settings per blog
Your own Wordpress.com
5Basically this is the meat behind Wordpress.comGreat for Uni’s, EducaEonal places, newspapers, blog networks etc
User Interface
6
User Interface
7
User Interface
8
User Interface
9
Admin Interface
10
Admin Interface
11
Admin Interface
12
Hooks and Filters
add_action($tag, $function, $priority, $accepted_args)
add_filter($tag, $function, $priority, $accepted_args)
http://www.flickr.com/photos/gaetanlee/2906941718/
add_shortcode($tag, $function)
13Don’t hack at the core code – makes it difficult to update the your installaEonUse hooks and filters to ‘inject’ an event into the page processing
Filters are the hooks that WordPress launches to modify text of various types before adding it to the database or sending it to the browser screen
Hooks aOach custom funcEons onto specific acEonshOp://codex.wordpress.org/Plugin_API/AcEon_ReferencehOp://codex.wordpress.org/Plugin_API/Filter_ReferencehOp://codex.wordpress.org/Shortcode_API
Where to put your code
PluginsInside it’s own file
Theme folder in the file
functions.php
14Plugins advantage – easily switch off and onableFuncEons – will always run – best if required as part of your theme (not covered today but example would be to change something a theme relies on – maybe the movement of a login buOon)
Simple Filter
<?php
function changeWord($content) { $search = “wordpress”; $replace = “my blog”; return str_ireplace($search, $replace, $content);}
add_filter(‘the_content’, ‘changeWord’);
?>
http://codex.wordpress.org/Plugin_API/Filter_Reference
15‘the_content” is a built in Wordpress tagStr_ireplace is case insensiEve
To test this included it in funcEons.php
Simple Filter
<?php
function changeWord($content) { $search = “wordpress”; $replace = “my blog”; return str_ireplace($search, $replace, $content);}
add_filter(‘the_content’, ‘changeWord’);
?>
http://codex.wordpress.org/Plugin_API/Filter_Reference
16‘the_content” is a built in Wordpress tagStr_ireplace is case insensiEve
To test this included it in funcEons.php
Simple Filter
Before After
17
Simple Hook
<?php
function addText() { echo “Can you see me?”;}
add_action(’wp_footer', ’addText’);
?>
http://codex.wordpress.org/Plugin_API/Action_Reference
18wp_footer Runs when the template calls the wp_footer funcEon, generally near the boOom of the blog page.
Simple Hook
<?php
function addText() { echo “Can you see me?”;}
add_action(’wp_footer', ’addText’);
?>
http://codex.wordpress.org/Plugin_API/Action_Reference
19wp_footer Runs when the template calls the wp_footer funcEon, generally near the boOom of the blog page.
Simple Hook<?php
function changeTextCol() { echo “ <style type=‘text/css’> body { color: #0ff00f; } </style> “;}
add_action(’wp_head', ’changeTextCol’);
?>
http://codex.wordpress.org/Plugin_API/Action_Reference
20wp_footer Runs when the template calls the wp_footer funcEon, generally near the boOom of the blog page.
Simple Hook
Before After
21
Simple Shortcode<?php
function myH1_shortcode($atts, $content = null) { extract($atts); return ‘ <div class=“heading”> <h1 style=“color:’ . $colour . ‘”>' . $content . '</h1> </div>’;}
add_shortcode(’heading', 'myH1_shortcode');
?>
http://codex.wordpress.org/Shortcode_API
22Shortcodes cannot be nested be default. Must add do_shortcode($content) into your handler to do this
Since WP2.5 (fixed 2.5.1. parsing order)
Note this isn’t really safe, $content should be saniEzed first using (stripslashes(wp_filter_post_kses($content) and colour should be protected with aOribute_escape($colour)
Simple Shortcode<?php
[heading color=“#f00”]This is my heading[/heading]
?>
Output
<div class="heading"> <h1 style="color:#f00">This is my heading</h1></div>
23Shortcodes cannot be nested be default. Must add do_shortcode($content) into your handler to do this
Namespacing
http://www.flickr.com/photos/thost/2244046981/24
Namespacing
<?php
function addText() { echo “Can you see me?”;}
add_action(’wp_footer', ’addText’);
?>
25
Namespacing
<?php
function tmh_addText() { echo “Can you see me?”;}
add_action(’wp_footer', ’tmh_addText’);
?>
26
Widgets
27
Plugin Code Structure<?php
/*Plugin Name: My WidgetPlugin URI: http://themattharris.comDescription: A widget that puts some text in the sidebarAuthor: Matt HarrisVersion: 1.0Author URI: http://themattharris.com*/
?>
28
Widget Code Structure<?php
function tmh_renderWidget($args) { extract($args); ?> <?php echo $before_widget; ?> <?php echo $before_title . wptexturize(’My Widget') . $after_title; ?> <p>My Widget Code</p> <?php echo $after_widget; ?> <?php}
?>
29
Widget Code Structure<?php
function tmh_renderWidget($args) { extract($args); ?> <?php echo $before_widget; ?> <?php echo $before_title . wptexturize(’My Widget') . $after_title; ?> <p>My Widget Code</p> <?php echo $after_widget; ?> <?php}
?>
30
Widget Code Structure<?php
function tmh_renderWidget($args) { extract($args); ?> <?php echo $before_widget; ?> <?php echo $before_title . wptexturize(’My Widget') . $after_title; ?> <p>My Widget Code</p> <?php echo $after_widget; ?> <?php}
?>
31
Widget Code Structure<?php
function tmh_renderWidget($args) { extract($args); ?> <?php echo $before_widget; ?> <?php echo $before_title . wptexturize(‘My Widget’) . $after_title; ?> <p>My Widget Code</p> <?php echo $after_widget; ?> <?php}
?>
32wp_specialchars ‐ Like htmlspecialchars except don't double‐encode HTML enEEes
<?php
function tmh_renderWidget($args) { extract($args); ?> <?php echo $before_widget; ?> <?php echo $before_title . wptexturize(’My Widget') . $after_title; ?> <p>My Widget Code</p> <?php echo $after_widget; ?> <?php}
?>
Widget Code Structure
33
Widget Registration Code<?php
function tmh_widgetInit() { if (function_exists('register_sidebar_widget’)) { register_sidebar_widget('My Widget', 'tmh_renderWidget'); }}
add_action( 'widgets_init', 'tmh_widgetInit');
?>
34
Putting it all together<?php/*Plugin Name: My WidgetPlugin URI: http://themattharris.comDescription: A widget that puts some text in the sidebarAuthor: Matt HarrisVersion: 1.0Author URI: http://themattharris.com*/
function tmh_renderWidget($args) { extract($args); ?> <?php echo $before_widget; ?> <?php echo $before_title . wptexturize('My Widget') . $after_title; ?>
<p>My Widget Code</p>
<?php echo $after_widget; ?> <?php}
function tmh_widgetInit() { if ( function_exists('register_sidebar_widget') ) { register_sidebar_widget('My Widget', 'tmh_renderWidget'); }}
add_action( 'widgets_init', 'tmh_widgetInit');
?>
35
Making it work
36
Making it work
37
Making it work
38
Making it work
39
40
41
Protecting your blog
check_admin_referer($action, [$query_arg]);
Use with
wp_create_nonce($action);
Use this on any forms you have.
42
Protecting your blog
attribute_escape($text); // also tag escape
wp_filter_post_kses($data); // adds slashes
wp_filter_nohtml_kses($data); // adds slashes
Use these when outputting data
43aOribute_escape (used for escaping for HTML aOributes)
Kses checks for allow html (or removes it in nohtml)
Protecting your blog
<?php current_user_can($capability) ?>
http://codex.wordpress.org/Roles_and_Capabilities
<?php if (current_user_can(‘unfiltered_html’)) { $data = Wp_filter_post_kses($data); } else { $data = wp_filter_nohtml_kses($data); }?>
Example
44aOribute_escape (used for escaping for HTML aOributes)
Kses checks for allow html (or removes it in nohtml)
Translation friendly
http://codex.wordpress.org/Translating_WordPress
<?php __($message, $domain); ?>
<?php _e($message, $domain); ?>
<?php _e(“Title:”,’tmh_pluginname’); ?>
Example
45WP uses GNU geOext localizaEon framework
Message level translaEon
_e echos
__ doesn’t
Too much info to go into here on how to have wordpress do the translaEon, but its worth building this in from the start
$message is output/returned if no translaEon is found so always worth building this in
Help and More InformationWordpress Mailing Lists
http://codex.wordpress.org/Mailing_Lists
Wordpress Codex (or Google term + “codex”)
http://codex.wordpress.org/
Wordpress Support Forum
http://wordpress.org/support/
Writing a Plugin
http://codex.wordpress.org/Writing_a_Plugin
46Wordpres support forum – if the FAQ can’t helpGoogle search – whole community out there that can help
Matt Harrishttp://[email protected]
All the links: http://ma.gnolia.com/people/themattharris/tags/plugging%20into%20wordpress
Image credits:“Hello … my name is”: http://www.flickr.com/photos/thost/2244046981/“Hooks for hand”: http://www.flickr.com/photos/gaetanlee/2906941718/“Wordpress Logo”: http://wordpress.org/about/logos/
47
Top Related