@salcode

Making Your Code Easy To Extend

Sal Ferrarello / @salcode

Never Hack Core (or plugins)

Make Your Plugin Extensible

A study of the Raptor Button plugin

"Get Raptor" Button

When Clicked

Four Steps to a More Extensible Plugin

  • Internationalization
  • Add filters
  • Add actions
  • Use templates

Internationalization (I18n)

Preparing your plugin for translation

I18n

// Don't do this!
$btn_txt = 'Get Raptor';
$btn_txt = __(
	'Get Raptor',       // Text to translate.
	'fe-raptor-button'  // Plugin slug.
);

Add Filters

apply_filters()

$btn_txt = $btn_txt;
$btn_txt = apply_filters(
	'fe_raptor_btn_txt', // Unique filter name.
	$btn_txt             // Value to filter.
);

fe-raptor-button.php

$btn_txt = apply_filters(
	'fe_raptor_btn_txt', // Unique filter name.
	$btn_txt             // Value to filter.
);

my-code.php

add_filter( 'fe_raptor_btn_txt',

	function( $btn_txt ) {
		return 'Click for a surprise';
	}

);

Raptor Button with New Text

Where Do I Put My Code?

  • functions.php
  • a custom plugin you write
  • mu-plugins directory

mu-plugins ?

/wp-content/mu-plugins/

Example

/wp-content/mu-plugins/my-code.php

fe-raptor-button.php

$btn_txt = apply_filters(
	'fe_raptor_btn_txt', // Unique filter name.
	$btn_txt             // Value to filter.
);

my-code.php

add_filter( 'fe_raptor_btn_txt',

	function( $btn_txt ) {
		return 'Click for a surprise';
	}

);

Add Actions

do_action()

do_action( 'fe_before_raptor_btn_template' );

fe-raptor-button.php

do_action( 'fe_before_raptor_btn_template' );

my-code.php

add_action( 'fe_before_raptor_btn_template',
	function() {
		echo 'Clicking this could be scary';
	}
);
add_action( 'fe_before_raptor_btn_template',
	function() { ?>
<div class="alert alert-danger alert-dismissible"
		role="alert" style="margin: 10px;">
	<button type="button" class="close"
		data-dismiss="alert" aria-label="Close">
		<span aria-hidden="true">&times;</span>
	</button>
	<strong>Warning!</strong> Clicking this button
</div> <?php } );

Write email log in custom file?

do_action( 'fe_stop_emails_log',
	$mock_email
);

https://github.com/salcode/stop-emails/issues/10

stop-emails.php

do_action( 'fe_stop_emails_log',
	$mock_email
);

my-code.php

add_action( 'fe_stop_emails_log',
	function( $mock_email ) {
		  file_put_contents(
			  __DIR__ . '/email_sent.log',
			  print_r( $mock_email, true )
		  );
	}
);

Templates

fe-raptor-button.php

echo '';

Templates

fe-raptor-button.php (refactored)

echo '';

Templates

fe-raptor-button.php

include __DIR__ . '/templates/btn.php';

templates/btn.php

<button data-fe-raptor="trigger">
	<?php echo esc_html( $btn_txt ); ?>
</button>

We can use a variable

$tmpl = __DIR__ . '/templates/btn.php';
include $tmpl;
$tmpl = get_stylesheet_directory() .
	'/fe-raptor-button/btn.php';

if ( ! file_exists( $tmpl ) ) {
	// Fallback to default template.
	$tmpl = __DIR__ . '/templates/btn.php';
}

include $tmpl;

btn.php (plugin)

<button data-fe-raptor="trigger">
	<?php echo esc_html( $btn_txt ); ?>
</button>

themes/bootstrap-genesis/fe-raptor-button/btn.php

<p class="text-center">
	<button data-fe-raptor="trigger"
		class="btn btn-danger btn-large">

		<?php echo esc_html( $btn_txt ); ?>

	</button>
</p>

Custom Template From Theme

Templates with Shortcodes

Shortcodes do NOT echo

Output Buffering

ob_start();
echo 'Example text';
$output = ob_get_clean();
// This code does NOT echo anything.
// $output now contains 'Example text';
$tmpl = get_stylesheet_directory().'/mysc/sc.php';

if ( ! file_exists( $tmpl ) ) {
	$tmpl = __DIR__ . '/templates/sc.php';
}

ob_start();
include $tmpl;
$output = ob_get_clean();
return $output;

Review

  • Internationalization (I18n)
  • Add filters
  • Add actions
  • Use templates

Iron Code Studio

Sal Ferrarello

salcode.com/extend-plugin

@salcode

Credits