I'm trying to speed up a WordPress website which uses Visual Composer plugin. In GTmetrix result I see this:
Serve resources from a consistent URL
https://example.com/wp-content/uploads/2015/02/sfondo_form.jpg?id=15129
The image with query string ?id=XXX is background of a column in Visual Composer. How can I disable it?
All these queries are in the VC custom shortcode. Check the picture below:
In case that might be helpful to anyone - I modified regex query to fetch all background styles:
$value = preg_replace('/(url\(\S+\.(jpg|jpeg|png|svg|gif))\?id=\d+(\))/', '$1$3', $value);
Background styles save in post_meta table. Here is how VC add custom CSS in a page body:
$shortcodes_custom_css = get_post_meta( $id, '_wpb_shortcodes_custom_css', true );
if ( ! empty( $shortcodes_custom_css ) ) {
$shortcodes_custom_css = strip_tags( $shortcodes_custom_css );
echo '<style type="text/css" data-type="vc_shortcodes-custom-css">';
echo $shortcodes_custom_css;
echo '</style>';
}
So we can filter post_meta value and VC output as we want:
add_filter('get_post_metadata', 'theme_prefix_vc_fix_shortcodes_custom_css', 10, 4);
function theme_prefix_vc_fix_shortcodes_custom_css($value, $object_id, $meta_key, $single) {
if ($meta_key!='_wpb_shortcodes_custom_css' || is_admin()) {
return $value;
}
// filter data for _wpb_shortcodes_custom_css only and not for admin
remove_filter('get_post_metadata', 'theme_prefix_vc_fix_shortcodes_custom_css', 10);
$value = get_metadata('post', $object_id, $meta_key, $single);
// we need to remove filter here because get_metadata function use "get_post_metadata" hook so we will have loop if not remove filter
if ($value) {
// you can use another regular expression, this is what I created quickly
$value = preg_replace("/(background-image[:\s]+url\(\S+\.(jpg|jpeg|png|svg|gif))\?id=\d+(\))/", "$1$3", $value);
}
add_filter('get_post_metadata', 'theme_prefix_vc_fix_shortcodes_custom_css', 10, 4);
return $value;
}
Alternatively, you can use the_content filter to remove ?id=XXXX from background images in document body.
Related
I am using Advanced Custom Fields Pro and ACF Frontend.
I am trying to remove the image from wordpress media library when a user deletes the image from the image field.
This is what I did:
//ACF Remove Image From WP Media Library
function delete_image( $value, $post_id, $field ) {
$old_value = get_field( $field['local-avatar'], $post_id, false /* Don't format the value, we want the raw ID */ );
if ( $old_value && ( int ) $old_value !== ( int ) $value )
wp_delete_attachment( $old_value, true );
return $value;
}
add_filter( 'acf/update_value/type=image', 'delete_image', 10, 3 );
I got to this by googling:
https://wordpress.stackexchange.com/questions/199887/wordpress-acf-delete-image-from-media-library
Furthermore, to find a solution, I also searched and documented myself on: https://www.advancedcustomfields.com/resources/
Unfortunately it's not working for me, I don't understand what I'm doing.
I am new to Wordpress and php, does anyone have any idea how to solve this problem ?
I'm trying to remove spaces automatically from data entered into a custom field generated by the ACF plugin when a custom post is updated or saved in wordpress.
I believe I need to use the acf/save_post hook but I'm struggling to get the preg_replace to work. I wonder if I'm not using the right identifier as the custom field name has field name postcodes but when inspected it has name fields[field_55c7969262970]. Can't seem to make it work with that either.
function remove_spaces( $post_id ) {
if( empty($_POST['postcodes']) ) {
return;
} else{
$postcodes = $_POST['postcodes'];
$postcodes = preg_replace('/\s+/', '', $postcodes);
return $postcodes; }
}
add_action('acf/save_post', 'remove_spaces', 1);
I think you are better off using the acf/update_value filter. From thr docs: "This hook allows you to modify the value of a field before it is saved to the database."
function remove_spaces($value, $post_id, $field) {
if(empty($value)) {
return;
}
$value = preg_replace('/\s+/', '', $value);
return $value;
}
add_filter('acf/update_value/name=postcodes', 'remove_spaces', 10, 3);
I am making a WordPress theme and I want to add different icons for Category. Basically I want if I select Music category while adding a WordPress Post then there should be Music icon before category in single post.
( Screenshot added)
If I select Image category then there should be Image icon before category in Single Post Page. I am using WordPress and I actually saw this work on this WordPress theme:
I am planning to use Font-Awesome icons... Anyone here for help :)
Apply a filter on the_category hook to modify the HTML of your the_category function and add a class name. This code was obtained from a WordPress StackExchange answer.
function add_class_callback( $result ) {
$class = strtolower( $result[2] );
$class = str_replace( ' ', '-', $class );
$replacement = sprintf( ' class=""><i class="fa %s"></i>%s</a>', $class, $result[2] );
return preg_replace( '#>([^<]+)</a>#Uis', $replacement, $result[0] );
}
function add_category_slug( $html ) {
$search = '#<a[^>]+(\>([^<]+)\</a>)#Uuis';
$html = preg_replace_callback( $search, 'add_class_callback', $html );
return $html;
}
add_filter( 'the_category', 'add_category_slug', 99, 1 );
The above function should add the required markup. Then, include the following CSS in you stylesheet.
.post-categories .music:before {
content: "\f001";
}
I would like to provide support for post formats in my first public theme (I usually do custom builds for clients) and would like to know, hopefully definitively, how to get the various different bits of content out, particularly for the index, and not with regards to the template hierarchy but rather extracting the specific data(ie: a video or audio URL, a gallery, a quote and author etc) from the_content().
Whats the common or standard way of doing it - I assume filtering the content to work with these ? any links / tutorials, suggestion etc are welcome.
To Summarize I'm after two things
a) Should I be supporting post formats at all
b) is there a standard way of doing it?
What I'm using right now for video (for example) is (with a custom metabox):
<?php
// Display Videos
// Utility function - allow us to strpos an array
if ( ! function_exists( 'video_strpos_arr' )) {
function video_strpos_arr($haystack, $needle) {
if( !is_array($needle) ) $needle = array($needle);
foreach( $needle as $what ) {
if( ($pos = strpos($haystack, $what) ) !==false ) return $pos;
}
return false;
}
}
// Get Ready Display the Video
$embedCheck = array("<embed", "<video", "<ifram");// only checking against the first 6
$mykey_values = get_post_custom_values('_format_video_embed');
$media_to_display = '';
// check if the audio metabox is used
if ( isset($mykey_values) && !empty($mykey_values) ) {
// iterate over values passed
foreach ( $mykey_values as $key => $value ) {
if ( !empty($value) ) {
$firstCar = substr($value, 0, 6); // get the first 6 char.
// if its a http(s).
if ( strpos($firstCar, "http:/" ) !== false || strpos($firstCar, "https:" ) !== false ) {
// send it to wp_oembed to see if the link is oembed enabled.
(wp_oembed_get($value) !==false ?
$media_to_display = '<div class="video" style="width:100%; overflow:hidden;">' .
wp_oembed_get($value) . '</div>' :
// if not output a link.
$media_to_display = '<a class="button videolink" href="' .
$value . '" target="_blank">Video link: ' . the_title() . '</a>'
);
}
// if its the embed code that matches our array defined above.
else if ( video_strpos_arr($firstCar, $embedCheck ) !== false ) {
$media_to_display = '<div class="video" style="width:100%; overflow:hidden;">' .$value. '</div>';
}
}
}; // end foreach
} // end conditional
if ( is_singular() ) {
// output a filtered excerpt displaying the result of the conditionals above.
echo apply_filters('the_content', $media_to_display );
the_content();
} else {
// output a filtered excerpt displaying the result of the conditionals above.
get_template_part( 'loop/loop', 'indextitle' );
echo apply_filters('the_excerpt', $media_to_display );
?><p><?php the_excerpt(); ?></p>
Read More <?php
}
Which works with the meta box, and I could use a function like this to grab the URL and pass it instead of the metabox value and then filter it out of the_content()
function nona_url_grabber() {
if ( ! preg_match( '/<a\s[^>]*?href=[\'"](.+?)[\'"]/is', get_the_content(), $matches ) )
return false;
return esc_url_raw( $matches[1] );
}
But I feel like thats a lot of PT for something that should have some support....
Personally I don't really use post formats, I tend to use custom post types instead, but as usual WP provides several ways to achieve the same result. Regardless, I think WP already has the information you need explained fairly well in the codex. In particular I think you'll find the information you want if you scroll down to just below the Function Reference content block, starting with Adding Theme Support.
In short, you can just modify your theme template files to check for the post format and output differently based on that value. For example, you might check if( has_post_format('photo') ), and only output the featured image for the post if it matches, or the entire normal loop if it doesn't. You could do a switch statement, or have a bunch of other conditionals in the template. You can even use separate template files (see here, eg. taxonomy-post_format-post-format-<formatname>.php ). I don't know that there's a standard or preferred approach, I suggest you choose whatever fits best into your workflow.
How do I modify a page title for specific pages in shortcode?
The following will change the title but it executes for every page. I need more control over where it executes.
function assignPageTitle(){
return "Title goes here";
}
add_filter('wp_title', 'assignPageTitle');
Is there a way to call the above in a shortcode function? I know how to use do_shortcode() but the above is a filter.
My goal is to modify the page title based on a URL parameter. This only happens for specific pages.
Although WordPress shortcodes was not designed to do this, it can be done. The problem is shortcodes are processed AFTER the head section is sent so the solution is to process the shortcode BEFORE the head section is sent.
add_filter( 'pre_get_document_title', function( $title ) {
global $post;
if ( ! $post || ! $post->post_content ) {
return $title;
}
if ( preg_match( '#\[mc_set_title.*\]#', $post->post_content, $matches ) !== 1 ) {
return '';
}
return do_shortcode( $matches[0] );
} );
add_shortcode( 'mc_set_title', function( $atts ) {
if ( ! doing_filter( 'pre_get_document_title' ) ) {
# just remove the shortcode from post content in normal shortcode processing
return '';
}
# in filter 'pre_get_document_title' - you can use $atts and global $post to compute the title
return 'MC TITLE';
} );
The critical point is when the filter 'pre_get_document_title' is done the global $post object is set and $post->post_content is available. So, you can find the shortcodes for this post at this time.
When the shortcode is normally called it replaces itself with the empty string so it has no effect on the post_content. However, when called from the filter 'pre_get_document_title' it can compute the title from its arguments $atts and the global $post.
Taken from the WordPress Codex
Introduced in WordPress 2.5 is the Shortcode API, a simple set of
functions for creating macro codes for use in post content.
This would suggest that you can't control page titles using shortcodes as the shortcode is run inside the post content at which point the title tag has already been rendered and is then too late.
What is it exactly that you want to do? Using the Yoast SEO Plugin you can set Post and Page titles within each post if this is what you want to do?
You could create your custom plugin based on your URL parameters as so:
function assignPageTitle(){
if( $_GET['query'] == 'something' ) { return 'something'; }
elseif( $_GET['query'] == 'something-else' ) { return 'something-else'; }
else { return "Default Title"; }
}
add_filter('wp_title', 'assignPageTitle');