I'm trying to accomplish an hard task. The task is removing a echo from a Yoast SEO file using the available WP hooks.
class-frontend.php
public function head() {
global $wp_query;
$old_wp_query = null;
if ( ! $wp_query->is_main_query() ) {
$old_wp_query = $wp_query;
wp_reset_query();
}
/**
* Action: 'wpseo_head' - Allow other plugins to output inside the Yoast SEO section of the head section.
*/
do_action( 'wpseo_head' );
echo '<!-- / ', $this->head_product_name(), ". -->\n\n"; // <-- remove this
if ( ! empty( $old_wp_query ) ) {
$GLOBALS['wp_query'] = $old_wp_query;
unset( $old_wp_query );
}
return;
}
Is there a way to override this function and remove the echo using the available WP hooks? Or is there a better way to do this?
Many thanks.
There is a post at wordpress.stackexchange that indicates you can output buffer using the hooks get_header and wp_head to filter that out:
add_action('get_header', 'ad_ob_start');
add_action('wp_head', 'ad_ob_end_flush', 100);
function ad_ob_start() {
ob_start('ad_filter_wp_head_output');
}
function ad_ob_end_flush() {
ob_end_flush();
}
function ad_filter_wp_head_output($output) {
if (defined('WPSEO_VERSION')) {
$output = str_ireplace('<!-- / Yoast WordPress SEO plugin. -->', '', $output);
}
return $output;
}
That expects your $this->head_product_name() to be / Yoast WordPress SEO plugin. so you may have to alter that...or if you want it to remove "anythere" there, you can change your replacement to something like this:
$output = preg_replace('/<!-- .* -->/Us', '', $output);
But that will remove ALL comments, and it will be slower than the string replace.
Related
I'm writing a simple plugin for wordpress that changes a single word on a page or a post to make it bold.
For example: vlbs -> vlbs
It works fine for normal Wordpress pages and posts with this code:
defined('ABSPATH') or die('You can\'t enter this site');
class VLBS {
function __construct() {
}
function activate() {
flush_rewrite_rules();
}
function deactivate() {
flush_rewrite_rules();
}
function unstinstall() {
}
function new_content($content) {
return $content = str_replace('vlbs','<strong style="color:#00a500">vlbs</strong>', $content);
}
}
if(class_exists('VLBS')){
$VLBS = new VLBS();
}
add_filter('the_content', array($VLBS, 'new_content'));
//activation
register_activation_hook(__FILE__, array($VLBS, 'activate'));
//deactivation
register_deactivation_hook(__FILE__, array($VLBS, 'deactivate'));
However, it does not work on a page built with Yootheme Pro Pagebuilder. Whatever is done within the function new_content() is processed after the content has already been loaded. Thus, I cannot manipulate it before it is displayed to the user.
So the question would be: How can I get the content of a page before it is displayed? Is there an equivalent to Wordpress' 'the_content'?
Any help is really appreciated! Thank you very much in advance.
Best regards
Fabian
Yootheme: 1.22.5
Wordpress: 5.2.4
PHP: 7.3
Browser: Tested on Chrome, Firefox, Edge, Internet Explorer
In your code, do you are sure it's the good usage of add_filter content ?
In the doc, the 2nd parameter is string, not array:
add_filter( 'the_content', 'filter_the_content_in_the_main_loop' );
function filter_the_content_in_the_main_loop( $content ) {
// Check if we're inside the main loop in a single post page.
if ( is_single() && in_the_loop() && is_main_query() ) {
return $content . esc_html__("I'm filtering the content inside the main loop", "my-textdomain");
}
return $content;
}
In wordpress, the_content function display the content. There is an other function for get_the_content
Go to your page file and get the content. You can use str_replace and echo the new content after.
Example single.php :
if ( $query->have_posts() ) :
while( $query->have_posts() ) : $query->the_post();
$content = get_the_content();
$new_content = str_replace(search, replace, $content);
echo $new_content;
endwhile;
endif;
If it is not possible for you, try to use the output buffer functions. If you need use this functions, I say it and I developpe more this part. But test the solution above before.
Oh, and it exist a special community for WP where your question will more pertinent : https://wordpress.stackexchange.com/
I am trying to echo visual composer shortcodes onto a page.
I've tried both methods below, but they don't work:
functions.php:
Method 1
/*
* add shortcode file
*/
function include_file($atts) {
$a = shortcode_atts( array(
'slug' => 'NULL',
), $atts );
if($slug != 'NULL'){
ob_start();
get_template_part($a['slug']);
return ob_get_clean();
}
}
add_shortcode('include', 'include_file');
Method 2
function someshortocode_callback( $atts = array(), $content = null ) {
$output = "[vc_section full_width=\"stretch_row\" css=\".vc_custom_1499155244783{padding-top: 8vh !important;padding-bottom: 5vh !important;background-color: #f7f7f7 !important;}\"][vc_row 0=\"\"][vc_column offset=\"vc_col-lg-offset-3 vc_col-lg-6 vc_col-md-offset-3 vc_col-md-6\"][/vc_column][/vc_row][/vc_section]";
return $output;
}
add_shortcode('someshortocode', 'someshortocode_callback');
file_rendering_vc_shortcodes.php:
Method 1
<?php if ( is_plugin_active( 'js_composer/js_composer.php' ) ) {
wc_print_notice('js_composer plugin ACTIVE', 'notice');
echo do_shortcode('[include slug="vc_templates/shop-page"]');
}; ?>
Result
js_composer plugin ACTIVE
shortcode is on page with parentheses as is
Method 2
<?php $post = get_post();
if ( $post && preg_match( '/vc_row/', $post->post_content ) ) {
// Visual composer works on current page/post
wc_print_notice('VC ON', 'notice');
echo add_shortcode('someshortocode', 'someshortocode_callback');
} else {
wc_print_notice('VC OFF', 'notice');
//echo do_shortcode('[include slug="vc_templates/shop-page"]');
}; ?>
Result
VC OFF (obviously, since the vc_row in shortcode is not there)
shortcode is NOT on page
shop-page.php
<?php
/**
Template Name: Shop Page in theme
Preview Image: #
Descriptions: #
* [vc_row][vc_column][/vc_column][/vc_row]
*/
?>
[vc_section full_width="stretch_row" css=".vc_custom_1499155244783{padding-top: 8vh !important;padding-bottom: 5vh !important;background-color: #f7f7f7 !important;}"][vc_row 0=""][vc_column offset="vc_col-lg-offset-3 vc_col-lg-6 vc_col-md-offset-3 vc_col-md-6"][/vc_column][/vc_row][/vc_section]
Is it possible to render vc shortcodes on page, and if so, how is it done?
Use the:
WPBMap::addAllMappedShortcodes();
then as usual do_shortcode($content);
In short, page builder due to performance doesn't register shortcodes unless it isn't required.
If your element is registered by vc_map or vc_lean_map then no need to use add_shortcode function, you can do everything just by using WPBMap::addAllMappedShortcodes(); it is will call an shortcode class callback during the rendering process and then shortcode template.
Regarding Method 2.
You have to use do_shortcode() in your shortcode function.
function someshortocode_callback( $atts = array(), $content = null ) {
$output = '[vc_section full_width="stretch_row" css=".vc_custom_1499155244783{padding-top: 8vh !important;padding-bottom: 5vh !important;background-color: #f7f7f7 !important;}"][vc_row 0=""][vc_column offset="vc_col-lg-offset-3 vc_col-lg-6 vc_col-md-offset-3 vc_col-md-6"]column text[/vc_column][/vc_row][/vc_section]';
return do_shortcode( $output );
}
add_shortcode( 'someshortocode', 'someshortocode_callback' );
Working example on my test site: http://test.kagg.eu/46083958-2/
Page contains only [someshortocode]. Code above is added to functions.php.
In your code for Method 2 there is another error: line
echo add_shortcode('someshortocode', 'someshortocode_callback');
cannot work, as add_shortcode() returns nothing. This code should be as follows:
<?php $post = get_post();
if ( $post && preg_match( '/vc_row/', $post->post_content ) ) {
// Visual composer works on current page/post
wc_print_notice('VC ON', 'notice');
} else {
wc_print_notice('VC OFF', 'notice');
add_shortcode('someshortocode', 'someshortocode_callback');
echo do_shortcode('[someshortocode]');
}; ?>
I've got wp_link_pages added to the bottom of my posts using this in functions.php:
function custom_pagination( $content ) {
if( is_singular() ) {
$content .= wp_link_pages('echo=0');
}
return $content;
}
add_filter( 'the_content','custom_pagination', 1 );
However this only adds it to the bottom but I'd also like to add them to the top of the post how would I go about achieving this? I'm having to use the function method due to also using jetpack related posts (Which the links appear below it if I don't use this method).
Thanks!
Your script is appending (i.e. .=) the wp_link_pages. Instead, you could do something like:
function custom_pagination( $content ) {
if( is_singular() ) {
$content = wp_link_pages('echo=0') . $content . wp_link_pages('echo=0');
}
return $content;
}
add_filter( 'the_content','custom_pagination', 1 );
I need to show excerpts of different lengths, so I use
function custom_excerpt($length) {
get_the_content();
... clean up and trim
return $excerpt;
}
however, I want to detect if a manual excerpt was entered in order to use that instead of the custom one. Is there a way to do this?
I tried by using
$wp_excerpt = get_the_excerpt();
But that returns the manual excerpt, and if the manual excerpt is empty, it automatically generates an excerpt of 55 characters, which doesn't help, because it will always be "true" (can't check if empty).
The reason for approaching it this way is because I have multiple excerpts on a single page (different lengths), and if the length needed is longer than the WordPress excerpt (55), I want to show my excerpt, unless a manual excerpt was written, in which case I want to show that.
It would be perfect if I could simply
if ( manual_excerpt() == true ) {
}
You need only replace the excerp_length wordpress default function, just follow the above code, then you can call this custom function and set the length:
<?php
// custom excerpt length
function custom_excerpt_length( $length = 20 ) {
return $length;
}
add_filter( 'excerpt_length', 'custom_excerpt_length', 999 );
?>
ANSWER UPDATED II
Using inside a function:
<?php
function custom_excerpt( $length = 55 ) {
if( $post->post_excerpt ) {
$content = get_the_excerpt();
} else {
$content = get_the_content();
$content = wp_trim_words( $content , $length );
}
return $excerpt;
}
?>
This is an old question but I was looking for this, ended up here and didn't see the following function in the answers. To know if a post has a custom excerpt you can use the has_excerpt function:
<?php has_excerpt( $id ); ?>
Where $id is the post id. If non is given then the current post id will be used.
Check if the post_excerpt slot in the post object is empty or not:
global $post;
if( '' == $post->post_excerpt )
{
// this post does NOT have a manual excerpt
}
To turn this into a function:
function so19935351_has_manual_excerpt( $post )
{
if( '' == $post->post_excerpt )
return false;
return true;
}
Anyone know of a way to remove the main editor from the page edit screen? And not just with css. I've added a few other meta boxes with the tinymce and they collide with the main one.
I have a class that removes other meta boxes from the edit screen, but I cant get rid of the main editor this way. I've tried to add 'divpostrich' and 'divpost' to the array in the class (but with no luck):
class removeMetas{
public function __construct(){
add_action('do_meta_boxes', array($this, 'removeMetaBoxes'), 10, 3);
}
public function removeMetaBoxes($type, $context, $post){
/**
* usages
* remove_meta_box($id, $page, $context)
* add_meta_box($id, $title, $callback, $page, $context = 'advanced', $priority = 'default')
*/
$boxes = array( 'slugdiv', 'postexcerpt', 'passworddiv', 'categorydiv',
'tagsdiv', 'trackbacksdiv', 'commentstatusdiv', 'commentsdiv',
'authordiv', 'postcustom');
foreach ($boxes as $box){
foreach (array('link', 'post', 'page') as $page){
foreach (array('normal', 'advanced', 'side') as $context){
remove_meta_box($box, $type, $context);
}
}
}
}
}
$removeMetas = new removeMetas();
I have also tried removing the 'divpostrich' with jquery. But cant figure out where to put the js for it to work. When I remove the 'postdivrich' in the browser with firebug - my remaining tinymce fields work perfect.
Any ideas?
There is built in WP support for this so you don't have to fiddle directly with the globals and ensure forwards compatibility if they ever change how features are handled. The WP Core code does pretty much the exact same logic as #user622018 answer however
function remove_editor() {
remove_post_type_support('page', 'editor');
}
add_action('admin_init', 'remove_editor');
What you are looking for is the global $_wp_post_type_features array.
Below is a quick example of how it can be used
function reset_editor()
{
global $_wp_post_type_features;
$post_type="page";
$feature = "editor";
if ( !isset($_wp_post_type_features[$post_type]) )
{
}
elseif ( isset($_wp_post_type_features[$post_type][$feature]) )
unset($_wp_post_type_features[$post_type][$feature]);
}
add_action("init","reset_editor");
Add the following code to your functions.
function remove_editor_init() {
if ( is_admin() ) {
$post_id = 0;
if(isset($_GET['post'])) $post_id = $_GET['post'];
$template_file = get_post_meta($post_id, '_wp_page_template', TRUE);
if ($template_file == 'page-home.php') {
remove_post_type_support('page', 'editor');
}
}
}
add_action( 'init', 'remove_editor_init' );
Couldn't you just disable the TinyMCE editor, leaving the HTML editor, as your meta boxes are colliding with it? :)
To disable the editor you will need to edit your wp-config.php file and add this line to the top:
define('DISALLOW_FILE_EDIT', true);