I'm attempting to add a shortcode wordpress sites using a custom plugin. No matter how I try to register or call this, the shortcode does not seem to render.
I am using the default 2020 theme from Wordpress to test this.
This is the code that adds the shortcode:
add_shortcode(
'test',
function () {
return 'test output';
}
);
If I manually check this on the template:
var_dump(shortcode_exists('test'));
the following is generated on a page load:
boolean true
However, if the following is added to the page content, it does not load:
[test]
I have also added the following to the theme functions.php
add_filter( 'widget_text', 'do_shortcode' );
However, as this is not within a widget (just post text) I did this to eliminate this possibility. It did not help.
Edit:
I also added the following to the page:
do_shortcode(['test']);
This produces the required output.
Every single tutorial does the above, pretty much verbatim.
What am I missing?
To be clear: Using [test] in content to show the shortcode inside post body content is the required behaviour.
Try to change the test name, suddenly it is reserved, and secondly, print the entire shortcode
print do_shortcode('[mytest]'); // [test]
<?php
/*
Plugin Name: Test
Description: La la la fa
Version: 0.1.0
*/
function question($attrs, $content = null) {
return '???';
}
add_shortcode('question', 'question');
add_action('init', function() {
d(do_shortcode('Are you sure [question]'));
});
Methods to output content with handling of shortcodes
the_content();
get_the_content();
apply_filters('the_content', $post->post_content);
Example:
add_action('init', function() {
d(apply_filters('the_content', 'Are you sure [question]')); // $post->post_content
});
This was a custom testing template, and the content of a post is not automatically parsed.
I've actually created a huge amount of custom meta data per post that I was arranging and presenting outside of the content, so I had used the $post->post_content property.
To be clear... $post->post_content is not parsed, the_content() is.
Things now work.
This is a good gotcha.
Related
So we have a custom page template in our Wordpress theme, that fetches 3 different pages' content and renders them into a tabbed layout. It includes the glossary section like so:
<div class="glossary-content content e8-tab-panel" data-tab="glossary">
<?php
$content = apply_filters( 'the_content', get_the_content( null, false, 80 ) );
echo ($content);
?>
</div>
When we use a block (like Kadence Blocks TOC) or another Table of Contents plugin, the TOC is not rendered.
If I modify the above and get rid of the apply_filters call, then the code for the TOC shows up as a comment.
<div class="glossary-content content e8-tab-panel" data-tab="glossary">
<?php
$content = get_the_content( null, false, 80 );
echo ($content);
?>
</div>
Gives me this in the content output:
<!-- wp:kadence/tableofcontents {"uniqueID": ...
Keeping the apply_filters call in there, strips the block info comments out.
Is there a filter I need to call in order to get this page to render custom blocks? Specifically the Kadence Blocks TOC, but really I'll use any TOC plugin at this point. I have a feeling that I am missing a step that will parse the content through all the filters registered by installed plugins, but my search has come up empty.
Thanks.
Went down a deep rabbit hole trying to figure out how to trigger the rendering of blocks. Turns out that WP relies heavily on a super global array and it must contain the Page to be rendered. But by default it is set to my containing page which is using this custom template (not my 3 loaded page fragments).
So I set it manually for each of the 3 sections before fetching and filtering the content.
<div class="glossary-content content e8-tab-panel" data-tab="glossary">
<?php
$GLOBALS['post'] = WP_Post::get_instance( 80 ); // Override to ensure block parsing.
$content = apply_filters( 'the_content', get_the_content( null, false, 80 ) );
echo $content;
?>
</div>
Interestingly you must set a post global value with an instance of WP_Post even though this is a Page.
Solution provided to me on Mastodon. Credit to #gmazzap#phpc.social.
A more "canonical" way of doing that is:
function my_render_post_content(int $id): void {
$GLOBALS['post'] = get_post($id);
the_content();
wp_reset_postdata();
}
This ensures full compatibility with plugins listening for different hooks and ensures you don't have issues accessing data from the "wrapper" page later.
I want to output a list of locations as a table and mark them up on a map. For this I have created a content type in WordPress with Pods with a property "Address". With a Pods shortcode, I am able to have the table created and list all the entries. With another Pods shortcode, I am able to generate a Leaflet shortcode.
The problem is that the Leaflet shortcode is output to the frontend, but is not interpreted by Leaflet as a map. If I use the Leaflet shortcode generated by Pods from the frontend in the backend, the map works as desired.
I'm afraid the problem arises because the shortcode generated by a shortcode is not taken into account and implemented.
I have created a WordPress page and noted the following shortcode:
[pods name="locations"]<br /><br />[/pods][pods name="locations"]<br />[leaflet-marker address="{#locations-address}"]<br />[/pods]
A correct shortcode is output in the frontend:
[leaflet-marker address="Ingolstädter Str. 101, 80939 München"]
In consultation with the developer of the Leaflet plugin for WordPress, I tried to insert the function with XYZ PHP code:
<?php
$a = do_shortcode( '[pods name="locations"][leaflet-marker]' . '[' . 'leaflet-marker address={#locations-address}' . ']' . '<br>[/pods]');
echo "[leaflet-map] $a [leaflet-marker]";
?>
The result is better, as the map is generated largely as desired, but when I insert the XYZ PHP code into the WordPress page, no map is output.
By default including a shortcode within a Pods shortcode will not work. If you need this functionality to work, you need to include the following constant in your wp_config.php file:
define('PODS_SHORTCODE_ALLOW_SUB_SHORTCODES',true);
Then, if you need to parse a shortcode within the Pods template, custom template or within your Pods shortcode, just add shortcodes=1 to the Pods shortcode.
Or you can use the filter below to have it always enabled:
add_filter( 'pods_shortcode', function( $tags ) {
$tags[ 'shortcodes' ] = true;
return $tags;
});
All these are explained at Pod's documentation.
I have found a solution in the meantime. The keyword is nested shortcodes (https://codex.wordpress.org/Shortcode_API) and the function "do_shortcode()".
Using a custom WordPress plug-in to run a script and output it as a custom shortcode, I was able to generate the map as desired. For this I used the following code. It is important to note that "do_shortcode()" must be used twice, first for Pods and then for Leaflet.
function map_func( $atts ){
$leaflet_map_shortcode = "[leaflet-map lat=48.13391418715657 lng=11.582841421510087 zoom=15 fitbounds max_zoom=19]";
$leaflet_map = do_shortcode($leaflet_map_shortcode);
$placese_marks_shortcode = '[pods name="places"]<br />[leaflet-marker address="{#places-address}" [...] [/leaflet-marker]<br />[/pods]';
$placese_marks = do_shortcode($placese_marks_shortcode);
$placese_marks2 = do_shortcode($placese_marks);
return $leaflet_map . $placese_marks2;
}
add_shortcode( 'map2', 'map_func' );
I'm developing a wordpress site where the posts are loaded in a popup with ajax (with Magnific Popup). The posts are using the template single.php.
This works fine, except that the header and footer are also loaded in the popup (html tags, navigation, scripts, …). I can of course delete get_header() and get_footer() from the template, but then the single post pages aren't loaded correctly via permalinks.
I tried conditional tags, but when the template is loaded with Ajax, it doesn't 'see' it's loaded on the homepage.
I think working with different templates is an option, although I have seen sites that work with the same template (like the Zoo theme on themeforest). But I couldn't figure out how it works there.
So I'm stuck here. Anybody?
The clean solution would be to use the WordPress AJAX functions.
Themes are nowadays usually split in multiple parts to reuse blocks in various places. For example, the theme twentysixteen uses get_template_part( 'template-parts/content', 'single' ); in the single.php to include the template file that shows the actual content of the file. You can use this easily to get the content of your post without header, footer etc.
First, set up the PHP part, you can just add this in the functions.php of your theme or directly in your plugin, dependant on what you are developing.
<?php
// for the admin area
add_action( 'wp_ajax_my_action', 'my_action_callback' );
// for the public area
add_action( 'wp_ajax_nopriv_my_action', 'my_action_callback' );
function my_action_callback() {
$postid = intval( $_POST['postid'] );
$post = get_post( $postid );
setup_postdata( $post );
get_template_part( 'template-parts/content', 'single' );
wp_die(); // this is required to terminate immediately and return a proper response
}
The corresponding JavaScript part:
var data = {
'action': 'my_action',
'postid': 1234
};
// since 2.8 ajaxurl is always defined in the admin header and points to admin-ajax.php
// on the frontend you have to set it yourself
var ajaxurl = '<?=admin_url( 'admin-ajax.php' )?>';
jQuery.post(ajaxurl, data, function(response) {
// alert('Got this from the server: ' + response);
// response will now contain your post, without header, footer, sidebars etc.
});
my_action is the identifyer for the whole process and has to be consistent between the two parts.
Documentation for WordPress AJAX support: https://codex.wordpress.org/AJAX_in_Plugins
I finally found out that this option is included in the Magnific Popup plugin: "To modify content after it’s loaded, or to select and show just specific element from loaded file, there is a parseAjax callback".
But I'll accept the above answer as I think this is an elegant way, instead of loading the whole page and only show the part needed.
I wanted to add shortcode from the text editor of wordpress post.I have added following short code in the post of wordpress:
<img alt="" src="[template_url]/images/ic_sol_1a.png" />
Here [template_url] is the shortcode i wanted to use it was not working. when i see it in the post page it render the text not the short code response. Somewhere i saw a solutions like adding following line to functions.php of theme:
add_filter( 'widget_text', 'shortcode_unautop');
add_filter( 'widget_text', 'do_shortcode');
But still after adding these lines i am unable to make shortcode work. What could be the possible reason?
my shortcode function is like this:
function my_template_url() {
return get_bloginfo('template_url');
}
add_shortcode("template_url", "my_template_url");
You will need to use the get_bloginfo() to return the value as in your example and make sure to use the_content() to print the value to the page. If you use one of the API methods such as get_the_content() then the do_shortcode filter is not run. If you want to apply it use the following:
function my_template_url() {
// This will echo the 'template_url'
return get_bloginfo('template_url');
}
add_shortcode("template_url", "my_template_url");
$shortcoded = apply_filters( 'the_content', get_the_content() );
You do not need the add_filter() lines.
After lots of headache and with the help of #doublesharp and #Nathan Dawson comments/answers we figured out Problem was inside single.php file of theme we were getting the content of post using get_the_content function. By changing it to the_content() function sortcodes start working. Please note that shortcode will not work in the visual editor of WordPress post on admin site but when you see the post actually in the browser by going to that post you can see it working.
Learning php, figure as well as following tutorials doing some practical useful stuff is import. So a wordpress plugin....
Trying to remove the favorite actions box that you get in the wordpress admin header.
<?php
/*
Plugin Name: Hide Favorite Actions
Plugin URI: http://www.mysite.com
Description: Allows you to remove the Screen Options and Help tabs from view
Author: Tai Havard
Version: 1.0
Author URI:
*/
add_action('admin_menu','removeHelpAndScreenOptions');
function removeHelpAndScreenOptions()
{
remove_action('favorite_actions');
}
?>
Plugins activated, function runs, I'm just not sure how to get hold of the favorite_actions correctly and wether remove_action is the correct function for use with the favorite_actions hook.
Thanks
Here's how remove action works:
remove_action( 'hook_name', 'function_name' );
That says you want to remove the function function_name from the hook hook_name. I don't know what the hook and function are fore removing help and screen options, though. If I remember correctly, those tabs are hardcoded into the actual admin pages.
I used that code and got an error in a template.php (presumably expecting an array) The box disappears if you return with an empty element, something like this:
add_filter('favorite_actions', 'no_fav');
function no_fav($actions) {
$actions = array(
'' => array(__(''), '')
);
return $actions;
}
I just deleted the strings, somebody could probably write a more elegant empty array.
In your plugin just add
function rb_ax() {
return;
}
add_filter( 'favorite_actions', 'rb_ax' );
And you're done.
this works for me, wp 3.0.5
/**
* Remove "Favorite actions" from Admin
*/
add_filter('favorite_actions', 'no_fav');
function no_fav($actions) {
return array();
}
I put it in functions.php, but it would probably work fine as a plugin.
returning nothing (void?) works, but writes Warning: Invalid argument supplied for foreach()...