WordPress.org

Ready to get started?Download WordPress

Forums

Picturefill.WP
[resolved] Run on other template tags beside the_content()? (7 posts)

  1. Andrew Tibbetts
    Member
    Posted 10 months ago #

    I'm looking to get this working for Advanced Custom Fields. Any direction on how to extend?

    http://wordpress.org/plugins/picturefillwp/

  2. kylereicks
    Member
    Plugin Author

    Posted 10 months ago #

    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, the cache_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.

  3. Andrew Tibbetts
    Member
    Posted 10 months ago #

    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 name

    I'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.

  4. Andrew Tibbetts
    Member
    Posted 10 months ago #

    Bingo!

    acf/load_value
    docs

    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!

  5. Andrew Tibbetts
    Member
    Posted 10 months ago #

    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!

  6. kylereicks
    Member
    Plugin Author

    Posted 10 months ago #

    Good sleuthing!

    The problem with the <br> tags seems to be a quirk with how Advanced Custom Fields handles acf/load_value. When a acf/load_value is called with content that is expected to contain HTML, the content is then passed though a format_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.

  7. kylereicks
    Member
    Plugin Author

    Posted 9 months ago #

    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.

Reply

You must log in to post.

About this Plugin

About this Topic