I'm trying to create a shortcode to render custom php pages. I'm getting very odd behaviour which i'm not getting if I used a wordpress template.
For example. If i create a template with the code:
<article id="post-<?php the_ID(); ?>" <?php post_class(); ?> <?php generate_article_schema( 'BlogPosting' ); ?>>
<div class="inside-article">
<?PHP $content = apply_filters( 'the_content', get_the_content() );
global $post;
$post_info = get_post($post->ID);
$content = $post_info->post_content;
$ind = strrpos($content, "/");
$page = substr($content, $ind+1);
$path = substr($content, 0, $ind+1);
$oldDir = getcwd();
chdir($_SERVER["DOCUMENT_ROOT"].$path);
include($page);
chdir($oldDir);
?>
</div><!-- .inside-article -->
</article><!-- #post-## -->
Then in the wordpress page i simply enter the location of the file, e.g. /contact/contact_form.php. The contact_form.php page renders on the screen within the wordpress theme.
Now, i recently discovered shortcodes, and thought these would be a better way of rendering the php on the page. Instead of having the content of the page as /contact/contact_form.php I could have [custom_php filepath="/contact/contact_form.php"]
This is where i'm getting problems. The contact_form.php seems to have many require_once() functions all over the place, yet the variables wtihin them don't seem to exist, even though the first method (above) works fine.
For my shortcode code I have:
function subscribe_custom_php_shortcode($atts, $content = null) {
$atts = shortcode_atts(
array(
'filepath' => '/index.php'
), $atts);
$ind = strrpos($atts["file"], "/");
$page = substr($atts["file"], $ind+1);
$path = substr($atts["file"], 0, $ind+1);
$oldDir = getcwd();
chdir($_SERVER["DOCUMENT_ROOT"].$path);
ob_start();
include($page);
$content = ob_get_clean();
chdir($oldDir);
return $content;
}
add_shortcode('custom_php', 'subscribe_custom_php_shortcode');
As you can see, the code is very similar except I added ob_start() and ob_get_clean() to get the results of the PHP based on someones comments. Removing these still doesn't seem to bring back the values of the require_conce within the contact_form.php.
What's interesting is if i change the require_once for include it works.
Any ideas?
Thanks
Assuming filepath is relative to theme directory, this should be the best way to include it...
function subscribe_custom_php_shortcode($atts, $content = null) {
$atts = shortcode_atts(
array(
'filepath' => '/index.php'
), $atts );
ob_start();
include get_stylesheet_directory() . $atts['filepath'];
$content = ob_get_clean();
return $content;
}
add_shortcode('custom_php', 'subscribe_custom_php_shortcode');
As you can see... we use the get_stylesheet_directory function to get the current theme directory.
Hope that helps 😉
Related
I am creating a private wordpress shortcode for an accordion, by using a simple plugin, created by myself.
The problem: Wordpress adds breaks and paragraphs to my HTML outcome, which leads to a broken design.
I can remove autobreaks, but then it also does not work for the real content, which has paragraphs. But I dont want to use p-tags in the backend.
How can I stop wordpress from doing autobreaks to my HTML, but still doing it for my wrapped content?
The solution has to work within a plugin - without affecting other plugins/functions.
I can remove any spacing between my shortcodes, so wordpress does not add any breaks. But thats very ugly to read.
This way it works:
[os_accordion][os_spoiler title="Title"]Content with some
breaks.[/os_spoiler][/os_accordion]
This way it does not:
[os_accordion]
[os_spoiler title="Title"]
Content with some
breaks.
[/os_spoiler]
[/os_accordion]
I tried to use a function for removing breaks, but it does not work.
//Helper to remove autops
function cleanup_shortcode_fix($content) {
$array = array('<p>[' => '[', ']</p>' => ']', ']<br />' => ']', ']<br>' => ']');
$content = strtr($content, $array);
return $content;
}
//Outer accordion wrapper
function function_accordion($atts, $content = null){
$html = '<div class="accordion">'.do_shortcode($content).'</div>';
return cleanup_shortcode_fix($html);
}
add_shortcode('os_accordion', 'function_accordion');
//Inner wraps
function function_spoiler($atts, $content = null){
//set default attributes and values
$values = shortcode_atts( array(
'title' => '',
), $atts );
//Output buffer
ob_start();
?>
<div class="toggle"><?php echo esc_attr($values['title']); ?></div>
<div class="content"><?php echo $content; ?></div>
<?php
return ob_get_clean(); //Close buffer and return data
}
add_shortcode('os_spoiler', 'function_spoiler');
Any ideas how I can make the last version work? I'm stuck. :/
This should do it. It's probably just putting p tags after everything.
remove_filter('the_content', 'wpautop');
Is there a way to get the content of an entire wordpress page? My problem is, I want to include page content on another page (to create a one-page layout). What I tried was this:
$post = get_post($the_page_id);
$content = apply_filters('the_content', $post->post_content);
echo $content;
But the page has its own template and I would like to display the entire page, including whatever is done in the template.php file. Is that possible?
Well, I came up with a solution for this. It might not be the best way but this worked for me. I created a page "home" to represent the one-page page. All subpages of this page will have a certain template which does not include header or footer. My home template looks like this:
//fetch header as usual
get_header();
//fetch all subpages of this page
$my_wp_query = new WP_Query();
$all_wp_pages = $my_wp_query->query(array('post_type' => 'page', 'orderby' => 'menu_order', 'order' => 'ASC'));
$children = get_page_children( get_the_ID(), $all_wp_pages );
//browse these subpages and get the content for each one
foreach($children as $child){
$post = get_post($child->ID);
getOnePageContent($post);
}
//footer
get_footer();
Now in functions.php I defined the getOnePageContent:
function getOnePageContent($page){
global $post;
$post = $page;
$slug = get_page_template_slug( $page->ID );
if($slug){
$pl = get_the_permalink($page);
$content = file_get_contents($pl);
echo $content;
} else {
$content = apply_filters('the_content', $page->post_content);
echo $content;
}
wp_reset_postdata();
}
As long as the subpages do not contain headers or footers this works fine. Of course, I do not think it's an elegant or good solution to fetch the page with file_get_contents but at least it works.
I have a slight issue. I have managed, with the help of someone one stackoverflow to write a code to add dynamic content to all my wordpress posts. The code is now in my functions.php file and is as follows.
function add_after_post_content($content) {
global $post;
if(!is_feed() && !is_home() && is_singular() && is_main_query()) {
$post_categories = wp_get_post_categories( $post->ID );
$cats = array();
foreach($post_categories as $c){
$cat = get_category( $c );
$cats[] = array( 'name' => $cat->name, 'slug' => $cat->slug );
}
$content .= '<strong>'. $post->post_title . '</strong> is a <strong>wallpaper</strong> posted in the ';
foreach($cats as $c){
$content .= $c['name'];
}
$content .= ' category by <strong>Free Wallpapers</strong> on '. $post->post_date . '. <br /><br />';
}
return $content;
}
add_filter('the_content', 'add_after_post_content');
The issue is that some of my older posts already have content in them and hence both the old content as well as the new are displayed beneath them. whereas I would like this to be the new content/description for all posts. Currently in my content-single.php I believe this is the line which calls the original post content plus the code I have mentioned above.
<?php the_content(); ?>
I would like to wither remove or modify my content-single.php/code added to functions.php file so that only the new code displays the dynamic description, and the original post content is not displayed. i.e. putting it simply if the entire new code could be labeled content2 and the content-single.php code will output this content2 only. I have tried simply moving the code from functions.php to replace
<?php the_content(); ?>
in the content-single.php but this gives me all kinds of errors.
Any help on this issue would be greatly appreciated.
Best Regards
Remove the dot after $content.
$content .= '<strong>'. $post->post_title . '</strong> is a <strong>wallpaper</strong> posted in the ';
Replace above line with following
$content = '<strong>'. $post->post_title . '</strong> is a <strong>wallpaper</strong> posted in the ';
I am trying to create a shortcode for 2 of my theme's options. Basically I want to grabe my theme options to my shortcode so that I can display them anywhere on my posts something like this:
[ads_1]
[ads_2]
However when I tried to get the options on my shortcode it wont work at all and its giving me an error
Parse error: syntax error, unexpected 'theme_settings' (T_STRING) in C:\xampp\htdocs\themewp\wp-content\themes\bots_final\shortcodes.php on line 86
Here's my snippet for my shortcode where in I am trying to grab my theme option data:
add_shortcode('ads_1', function($atts){
return '
<div>
<?php $options = get_option( 'theme_settings' ); ?>
<?php echo $options['banner1']; ?>
</div>';
});
I am trying to grab the options from my Theme options page. Check my theme options code:
<div>
<?php $options = get_option( 'theme_settings' ); ?>
<?php echo $options['banner1']; ?>
</div>
Any idea what's the problem why I can't grab it?
You opened the <?php inside an open php tag:
add_shortcode('ads_1', function($atts){
$html = '<div>';
$options = get_option( 'theme_settings' );
$html .= $options['banner1'];
$html .= '</div>';
return $html;
});
What do you get from get_option( 'theme_settings' );? It seems like your suggesting an array..
To avoid conflicts, I'd store your settings as 'mytheme_theme_settings'.
I am supporting a website running on Wordpress 3.8 with a wpzoom theme (zenko) on top of that with most of the articles posts running on multiple pages.
For pagination navigation we use the WP-PageNavi plugin http://wordpress.org/extend/plugins/wp-pagenavi/ with the function
<?php wp_pagenavi( array( 'type' => 'multipart' ) ); ?>
inserted in the single.php code after the
<?php the_content(); ?> function.
Recently we added the WordPress Related Posts http://wordpress.org/extend/plugins/wordpress-23-related-posts-plugin/ . However when activated the related posts appear before the page navigation links- buttons and I would prefer to change it to appear after them.
Looking around in the related post plugin's code I found the corresponding formating code as follows:
global $wp_rp_output;
$wp_rp_output = array();
function wp_rp_add_related_posts_hook($content) {
global $wp_rp_output, $post;
$options = wp_rp_get_options();
if ($content != "" && $post->post_type === 'post' && (($options["on_single_post"] && is_single()) || (is_feed() && $options["on_rss"]))) {
if (!isset($wp_rp_output[$post->ID])) {
$wp_rp_output[$post->ID] = wp_rp_get_related_posts();
}
$content = str_replace('%RELATEDPOSTS%', '', $content); // used for gp
$content = $content . $wp_rp_output[$post->ID];
}
return $content;
}
add_filter('the_content', 'wp_rp_add_related_posts_hook', 10);
My question is how can I modify the code so that the array of related post appear after the page navigation links