I want to make a ColorBox shortcode based on the ShortCodeScriptHandler class here and pasted below—http://scribu.net/wordpress/optimal-script-loading.html#comment-4499
The point of the class is to only load the Javascript when the shortcode is present on the page.
I know how to make shortcodes but am new to OOP, so can you walk me through this?
The two scripts that will have to be included are will be the ColorBox script itself (jquery.colorbox-min.js) and the script invoking the plugin on the page, which would take parameters from the shortcode, something like this:
$(".shortcodecontent").colorbox({width:"<?php echo $width; ?>", height:"<?php echo $height; ?>", iframe:true, transition:elastic});
The colorbox.css file would also have to be included.
This is what I need walking through (I don't fully understand what I have to do when he says "Implement the abstract method _____"):
<blockquote>1. Create a class for a new short that extends ShortCodeScriptLoader, e.g.
class YourSubclass extends ShortCodeScriptLoader {}
2. Implement the abstract method handle_shortcode() to do whatever
3. Implement the abstract method add_script() to add scripts calling wp_register_script() and wp_print_scripts()
4. Initialize the shortcode like:
$sc = new YourSubclass();
$sc->register('shortcode');</blockquote>
And here's the code:
abstract class ShortCodeLoader {
/**
* @param $shortcodeName mixed either string name of the shortcode
* (as it would appear in a post, e.g. [shortcodeName])
* or an array of such names in case you want to have more than one name
* for the same shortcode
* @return void
*/
public function register($shortcodeName) {
$this->registerShortcodeToFunction($shortcodeName, 'handle_shortcode');
}
/**
* @param $shortcodeName mixed either string name of the shortcode
* (as it would appear in a post, e.g. [shortcodeName])
* or an array of such names in case you want to have more than one name
* for the same shortcode
* @param $functionName string name of public function in this class to call as the
* shortcode handler
* @return void
*/
protected function registerShortcodeToFunction($shortcodeName, $functionName) {
if (is_array($shortcodeName)) {
foreach ($shortcodeName as $aName) {
add_shortcode($aName, array($this, $functionName));
}
}
else {
add_shortcode($shortcodeName, array($this, $functionName));
}
}
/**
* @abstract Override this function and add actual shortcode handling here
* @param $atts shortcode inputs
* @return string shortcode content
*/
public abstract function handle_shortcode($atts);
}
abstract class ShortCodeScriptLoader extends ShortCodeLoader {
var $doAddScript;
public function register($shortcodeName) {
$this->registerShortcodeToFunction($shortcodeName, 'handle_shortcode_wrapper');
// It will be too late to enqueue the script in the header,
// so have to add it to the footer
add_action('wp_footer', array($this, 'add_script_wrapper'));
}
public function handle_shortcode_wrapper($atts) {
// Flag that we need to add the script
$this->doAddScript = true;
return $this->handle_shortcode($atts);
}
// Defined in super-class:
//public abstract function handle_shortcode($atts);
public function add_script_wrapper() {
// Only add the script if the shortcode was actually called
if ($this->doAddScript) {
$this->add_script();
}
}
/**
* @abstract override this function with calls to insert scripts needed by your shortcode in the footer
* Example:
* wp_register_script('my-script', plugins_url('my-script.js', __FILE__), array('jquery'), '1.0', true);
* wp_print_scripts('my-script');
* @return void
*/
public abstract function add_script();
}
ColorBox is here: http://colorpowered.com/colorbox/
Peter Michael answers:
class SCColorbox extends ShortCodeScriptLoader {
function handle_shortcode( $atts ) {
extract( shortcode_atts( array(
'width' => 300,
'height' => 300,
), $atts ) );
$html = '<script>jQuery(".shortcodecontent").colorbox({width:'.$width.', height:'.$height.', iframe:true, transition:elastic});</script>';
return $html;
}
function add_script() {
wp_register_script( 'my-jquery-colorbox', 'path/to/jquery.colorbox-min.js', array('jquery'), '1.3.17' );
wp_print_scripts('my-jquery-colorbox');
wp_register_style( 'my-jquery-colorbox-css', 'path/to/colorbox.css', '', '1.3.17', 'screen, projection' );
wp_print_styles('my-jquery-colorbox-css');
}
}
$scc = new SCColorbox();
$scc->register('sccolorbox');
Untested, not sure if the CSS call works.
web559 comments:
The JS appears to work correctly, but the CSS is placed in the footer.
Also, I can't seem to wrap content with this shortcode. I changed handle_shortcode like so:
function handle_shortcode( $atts, $content = null )
and added $content to the $html that is returned:
return $html . $content;
but it didn't display any of the wrapped content, such as from
[sccolorbox]I am $content but I'm not showing up.[/sccolorbox]
Do you know how to fix? I can't give you a URL because I'm on localhost.
web559 comments:
Also—do you know why I'm unable to specify the wp_register_script URL with bloginfo("template_url")? When I used it, it was ignored.
wp_register_script( 'my-jquery-colorbox', bloginfo("template_url") . '/jquery.colorbox-min.js', array('jquery'), '1.3.17' );
So I had to hard code the /wp-content/themes/mytheme.
Peter Michael comments:
To return the content you will have to return the variable as well:
function handle_shortcode( $atts, $content = null ) {
extract( shortcode_atts( array(
'width' => 300,
'height' => 300,
), $atts ) );
$html = '<script>jQuery(".shortcodecontent").colorbox({width:'.$width.', height:'.$height.', iframe:true, transition:elastic});</script>';
$html .= $content;
return $html;
}
To get the template URL, use
wp_register_script( 'my-jquery-colorbox', get_template_directory_uri() . '/jquery.colorbox-min.js', array('jquery'), '1.3.17'
HTH
Peter Michael comments:
See attachment. Drop the folder 'colorbox' into your theme folder and add
require_once( 'colorbox/colorbox.php' );
to your theme's functions.php file