This is both a WordPress and a PHP question, since a PHP programmer may know a technique that the WP group doesn’t.
I have been attempting to write a shortcode that fires the Foundation Reveal code for use inline with the WP Editor. I envision having it work like this:
[reveal size="medium" bg="true" slug="page-slug"]Open a modal with this link![/reveal]
The shortcode specifies the modal size, whether or not to use the black background, and which page slug to incorporate content from in a custom single-page loop (which allows us to use a non-public custom post type to hold the modal data). There are additional attributes but I haven’t written them in yet in the interest of simplicity.
Here’s where it gets tricky.
A modal comes in two parts, the link and the hidden DIV. The DIV typically goes at the footer of the site. I could put it inline and solve my problem, but that would play havoc on Google’s webcache. No, the modal needs to be an aside in the footer.
So I got a bit clever. I had the short code return the target link, but I also had it register a hook (placed in footer.php) to which a content DIV is attached. Everything was working fine until I realized a problem with my variable scope. First, here’s my current code:
/**
* Foundation Reveal Shortcode
*/
// Create an action to be placed in the site footer. We will target this with the second half of the function
function foundation_reveal() {
do_action('foundation_reveal');
}
// Set up the shortcode for the modal
function reveal_setup($atts, $content) {
// Extract the attributes
extract(shortcode_atts(array(
'size' => 'medium',
'slug' => 'dummy',
'bg' => 'reveal-modal'
), $atts));
$modal_link = '<a href="#" data-reveal-id="' . $slug . '">';
$modal_link .= $content;
$modal_link .= '</a>';
if ($slug == 'dummy') {
$the_modal = '<div id="' . $slug . '" class="' . $size . ' ' . $bg . '" data-reveal>' . 'reminder/dummy content goes here' . '</div>';
} else {
$the_modal = '<div id="' . $slug . '" class="' . $size . ' ' . $bg . '" data-reveal>' . 'post loop based on page slug goes here' . '</div>';
}
function reveal_content($the_modal) {
echo $the_modal;
}
add_action('foundation_reveal', 'reveal_content');
return $modal_link;
}
/**
* Setup shortcodes for this theme
*/
// Register all shortcodes
function gmfi_shortcodes() {
add_shortcode('reveal', 'reveal_setup');
}
// Add shortcodes to the init hoook
add_action( 'init', 'gmfi_shortcodes');
And since it’s kind of helpful to see this whole thing color coded by my IDE, here’s a link to that image.
The problem will be evident to any PHP programmer right away. In order to pass something like $slug to the secondary function, which gets hooked into the footer, I would need to pass the variable by reference.
i.e., I would have to do this:
add_action('foundation_reveal', 'reveal_content($slug)');
That, unfortunately, is not how WordPress works.
So here’s the question then… can you think of another way to pass that variable by reference? Because if not, I may have to suck it up and write a custom hook/action script. That option seems wasteful if there is a way to do it using the available WordPress components. But, then again, if there was another way, one of the WordPress/Foundation plugin suites probably would have done it already.
Either way, I need you all to help me figure out my next step.
Thanks so much for sticking with me as I explained all of that!
Additional note: The foundation_reveal() hook in the footer definitely gets fired, it just doesn’t get any of the class or ID data passed to it.
There are different ways to get the result. You can use a class, store the div content in a class or instance variable and output it when needed.
As alternative you can use a function with a static variable, to hold the content.
I’ll use this second alternative, converting it in a class is an exercise for you 😉
In addiction you can use the core
'wp_footer'
hook to output the content, in this way you don’t have to add an additional hook, nor use a template tag.That’s all. Untested.
PS:
extract
usage is a bad practice, (although I know it’s largely used in core code and in Codex examples…)You could also use an anonymous function and let it access outside variables via the
use
keyword (if you got PHP 5.3+ ).Examples: