Run on other template tags beside the_content()?
-
I’m looking to get this working for Advanced Custom Fields. Any direction on how to extend?
-
Good question. Looking at the repository, I realize that this isn’t documented as well as it could be.
For a basic implementation, you are going to be interested in the
replace_images
method, or if you want to use transients for output caching, thecache_picturefill_output
method.You can call these methods on your other filter hooks from your functions.php file like this:
add_filter('the_other_filter', array(Picturefill_WP::get_instance(), 'replace_images'), 11);
To use transient caching with another content area, we need to add another step.
add_filter('the_other_filter', array(Picturefill_WP::get_instance(), 'theme_picturefill_wp_the_other_filter'), 11); function theme_picturefill_wp_the_other_filter($html, $post_id, $post_thumbnail_id, $size, $attr){ return Picturefill_WP::get_instance()->cache_picturefill_output($html, 'the_other_filter'); }
If your content area uses the standard WordPress image sizes (thumbnail, medium, large, full), then you are all set. No other configuration required.
If your content area uses a non-standard image size (for example “widget_image_small” set to 50px by 50px), then you will need a little more configuration.
First, following the example for responding to a custom image size:
// Add an @2x size for "widget_image_small" (assuming that widget area small already exists as a part of your theme) add_action('init', 'theme_add_widget_image_small_@2x_image_size'); function theme_add_widget_image_small_@2x_image_size(){ add_image_size('widget_image_small@2x', 100, 100); } // Make sure Picturefill.WP has the attachment data for widget_image_small and widget_image_small@2x add_filter('picturefill_wp_image_attachment_data', 'theme_picturefill_widget_image_small_attachment_data', 10, 2); function theme_picturefill_widget_image_small_attachment_data($attachment_data, $attachment_id){ $widget_image_small_data = array( 'widget_image_small' => wp_get_attachment_image_src($attachment_id, 'widget_image_small'), 'widget_image_small@2x' => wp_get_attachment_image_src($attachment_id, 'widget_image_small@2x') ); return array_merge($attachment_data, $widget_image_small_data); } // Add widget_image_small and widget_image_small@2x to the responsive queue add_filter('picturefill_wp_image_sizes', 'theme_add_widget_image_small_to_responsive_image_list', 11, 2); function theme_add_widget_image_small_to_responsive_image_list($default_image_sizes, $image_attributes){ return 'widget_image_small' === $image_attributes['size'][1] ? array( 'widget_image_small', 'widget_image_small@2x' ) : $default_image_sizes; } // Set the breakpoint for the new image as the new smallest size add_filter('picturefill_wp_media_query_breakpoint', 'theme_picturefill_widget_image_small_breakpoint', 10, 3); function theme_picturefill_widget_image_small_breakpoint($breakpoint, $image_size, $width){ return in_array($image_size, array('widget_image_small', 'widget_image_small@2x')) ? 1 : $breakpoint; }
I’ll take a closer look at the Advanced Custom Fields plugin, but it looks like running using the
acf/load_field/type={$field_type}
filter might do the trick.Something like:
add_filter('acf/load_field/type=image', array(Picturefill_WP::get_instance(), 'replace_images'), 11);
I’ll try to dedicate some time this weekend to testing out Picturefill.WP with the Advanced Custom Fields plugin and I will follow up with an answer more specific to that use case.
Thanks for your feedback, I’ll get back to you with more soon.
Holy due diligence! Thanks.
Just fooling around with it now and the docs for ACF say:There are 4 ways to hook into acf_load_field.
acf/load_field – filter for every field
acf/load_field/type={$field_type} – filter for a specific field based on it’s type
acf/load_field/name={$field_name} – filter for a specific field based on it’s name
acf/load_field/key={$field_key} – filter for a specific field based on it’s nameI’ve tried:
add_filter('acf/load_field', array(Picturefill_WP::get_instance(), 'replace_images'), 11);
and
add_filter('acf/load_field', 'theme_picturefill_wp_the_other_filter', 11); function theme_picturefill_wp_the_other_filter($html){ return Picturefill_WP::get_instance()->cache_picturefill_output($html, 'acf/load_field'); }
Neither of those worked. I’ll keep fooling around.
Bingo!
acf/load_value
These both work:
add_filter('acf/load_value', array(Picturefill_WP::get_instance(), 'replace_images'), 11);
add_filter('acf/load_value', 'theme_picturefill_wp_the_other_filter', 11); function theme_picturefill_wp_the_other_filter($html){ return Picturefill_WP::get_instance()->cache_picturefill_output($html, 'acf/load_value'); }
Now I will create a couple for the specific acf field types I need and I’m good to go.
Thanks for the help!Just a heads up:
Now that the img is being converted to spans, WP inserts a bunch of<br>
tags messing with the layout.
I got rid of all of them (except one stubborn one before the noscript tag) by nixing all returns and whitespace in the template files.
Cheers!Good sleuthing!
The problem with the
<br>
tags seems to be a quirk with how Advanced Custom Fields handlesacf/load_value
. When aacf/load_value
is called with content that is expected to contain HTML, the content is then passed though aformat_value_for_api
function which executes shortcodes,wpautop
, etc.To make sure Picturefill_WP is called after
wpautop
we need to use an undocumented filter,acf/format_value_for_api
.add_filter('acf/format_value_for_api', 'theme_function_picturefill_for_acf', 11, 3); function theme_function_picturefill_for_acf($content, $post_id, $field){ if(in_array($field['type'], array('textarea', 'wysiwyg'))){ return Picturefill_WP::get_instance()->cache_picturefill_output($content, $field['name']); }else{ return $content; } }
That should run the plugin over the text area and wysiwyg fields. When it comes to image fields, you will need to wrap your own filter around the image output.
In your theme file:
<?php $image_url = get_field('image'); $image_output = '<img src="' . $image_url . '" />'; echo apply_filters('theme_acf_image', $image_output, 'name_of_the_image_field'); ?>
In functions.php
add_filter('theme_acf_image', 'theme_function_for_acf_image', 10, 2); function theme_function_for_acf_image($content, $name_of_the_image_field){ return Picturefill_WP::get_instance()->cache_picturefill_output($content, $name_of_the_image_field); }
I think that might work a little better.
Added this solution to the documentation and to the FAQ. Unless there are any other problems, I’m going to call this closed. Thanks very much for bringing up the issue.
- The topic ‘Run on other template tags beside the_content()?’ is closed to new replies.