I have written a wordpress plugin. It is a collection of shortcodes which fetch, parse and render data from an API. I am now currently writing a theme to support this plugin. I'm noticing that Wordpress seperates shortcode content from editor content and renders them seperately. Here is an illustration of my issue: Editing a Page or a Post in the admin panel:
<div class="row">
<div class="col-lg-12">
<p>HERE</p>
[PluginShortcode_1]
</div>
</div>
Let's say that PluginShortcode_1 generates the following html:
<h1>This is the output of PluginShortcode_1</h1>
<p>Got Here!</p>
I would like to expect the output to be:
<div class="row">
<div class="col-lg-12">
<p>HERE</p>
<h1>This is the output of PluginShortcode_1</h1>
<p>Got Here!</p>
</div>
</div>
But rather, the following is sent to the browser:
<h1>This is the output of PluginShortcode_1</h1>
<p>Got Here!</p>
<div class="row">
<div class="col-lg-12">
<p>HERE</p>
</div>
</div>
Apparently wordpress does the following:
- Parse and render shortcode content
- Render post content
I've seen references to do_shortcode() But my plugin defines many shortcodes and would not explicitly know in the template.php which shortcode or shortcodes are on the page without parsing the content beforehand, selecting all of the shortcodes and applying the filters.
UPDATE:
The shortcode functions are within a set of classes which handle all of the rendering. Most of the shortcode content is store seperately in a "view" script which renders the content.
The example above would be invoked in the following way:
shortcodes.ini - a list of shortcodes and their associated functions:
[shortcode_values]
PluginShortcode_1 = shortcodeOne
AnotherShortcode = anotherShortcode
Shortcodes.php - container for shortcode functions and invocation:
public function __construct() {
$ini_array = parse_ini_file(__DIR__. '/shortcodes.ini', true);
$this->codeLib = $ini_array['shortcode_values'];
foreach ($this->codeLib as $codeTag => $codeMethod) {
add_shortcode($codeTag, array(&$this, $codeMethod));
}
}
public function shortcodeOne() {
require_once(__DIR__ . 'views/shortcodeOneView.php');
}
views/shortcodeOneView.php
<?php
?>
<h1>This is the output of PluginShortcode_1</h1>
<p>Got here!</p>
Where the shortcode function would actually be responsible for fetching data, setting variables which would be exposed to the view.
UPDATE To complicate matters further, since this plugin makes API requests, I restrict it to only be invoked if the post content actually contains a shortcode.
In the plugin initialization script, I have the following:
class myPlugin.php:
public function __construct() {
. . .
add_filter('the_posts', array(&$this, 'isShortcodeRequest'));
. . .
}
public function isShortcodeRequest($posts) {
if (empty($posts)) { return $posts; }
foreach ($posts as $post) {
if (stripos($post->post_content, '[PluginShortcode') !== false) {
$shortcodes = new Shortcodes();
break;
}
}
return $posts;
}
My concern is that this filter may be responsible for hijacking the output. . .(?)