Skip to content

Instantly share code, notes, and snippets.

@mattwiebe
Created September 21, 2011 23:02

Revisions

  1. mattwiebe revised this gist Sep 27, 2011. 1 changed file with 4 additions and 1 deletion.
    5 changes: 4 additions & 1 deletion responsive-images.php
    Original file line number Diff line number Diff line change
    @@ -2,7 +2,7 @@
    /*
    Plugin Name: Mobile First Responsive Images
    Description: Serve up smaller images to smaller screens.
    Version: 0.1
    Version: 0.1.1
    Author: Matt Wiebe
    Author URI: http://somadesign.ca/
    */
    @@ -51,6 +51,9 @@ function make_respnsive_image($image) {
    return $image;
    }
    $attachment = get_post($matches[1]);
    if ( ! $attachment || 'attachment' !== $attachment->post_type ) {
    return $image;
    }
    $small = wp_get_attachment_image_src( $attachment->ID, 'mobile-first' );
    $small_url = $small[0];

  2. mattwiebe revised this gist Sep 26, 2011. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion responsive-images.php
    Original file line number Diff line number Diff line change
    @@ -2,7 +2,7 @@
    /*
    Plugin Name: Mobile First Responsive Images
    Description: Serve up smaller images to smaller screens.
    Version: 1.0
    Version: 0.1
    Author: Matt Wiebe
    Author URI: http://somadesign.ca/
    */
  3. mattwiebe revised this gist Sep 21, 2011. 1 changed file with 13 additions and 9 deletions.
    22 changes: 13 additions & 9 deletions responsive-images.php
    Original file line number Diff line number Diff line change
    @@ -10,11 +10,12 @@
    /**
    * The smaller image is wrapped in a <noscript> tag so 1) it'll show up on non-JS browsers
    * and 2) it won't be partially downloaded on desktop browsers.
    *
    *
    * JS-enabled browsers will sniff the breakpoint for which size of image to sub in
    * Be sure to regenerate thumbnails after starting to use
    * Be sure to regenerate thumbnails after starting to use
    * or nothing will happen.
    * @link http://wordpress.org/extend/plugins/regenerate-thumbnails/
    *
    *
    * Won't work very well inside [caption] shortcodes
    * <noscript> concept: @link http://somad.es/5D
    */
    @@ -29,15 +30,13 @@ function init() {
    }
    // our image size
    add_image_size( 'mobile-first', MOBILE_FIRST_BREAKPOINT, MOBILE_FIRST_BREAKPOINT );

    // where the magic happens
    add_filter( 'the_content', array( __CLASS__, 'responsive_images' ) );

    // ensure jQuery is ready for our stuff later
    wp_enqueue_script('jquery');
    add_action( 'wp_footer', array( __CLASS__, 'swap_images_js' ), 11 );
    }



    function responsive_images($content) {
    $regex = '/<img .* wp-image-[0-9]{1,10}.* \/?>/';
    return preg_replace_callback( $regex, array( __CLASS__, 'make_respnsive_image' ), $content );
    @@ -55,6 +54,11 @@ function make_respnsive_image($image) {
    $small = wp_get_attachment_image_src( $attachment->ID, 'mobile-first' );
    $small_url = $small[0];

    // if it's the same as fullsize, this is useless
    if ( $attachment->guid === $small_url ) {
    return $image;
    }

    // if it's the same image, just return it
    if ( false !== strpos($image, $small_url) ) {
    return $image;
    @@ -76,7 +80,7 @@ function make_respnsive_image($image) {
    return $image;
    }
    unset($atts['width']);
    }
    }
    if ( isset($atts['height']) ) unset($atts['height']);
    // I think title attributes on images suck. Goodbye
    if ( isset($atts['title']) ) unset($atts['title']);
    @@ -99,7 +103,7 @@ function make_respnsive_image($image) {
    $return = "<span class=\"responsivize\" {$wrapper_atts}><noscript>{$return}</noscript></span>";
    return $return;
    }

    function swap_images_js() { ?>
    <script>
    var MOBILE_FIRST_BREAKPOINT = <?php echo MOBILE_FIRST_BREAKPOINT; ?>;
  4. mattwiebe created this gist Sep 21, 2011.
    125 changes: 125 additions & 0 deletions responsive-images.php
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,125 @@
    <?php
    /*
    Plugin Name: Mobile First Responsive Images
    Description: Serve up smaller images to smaller screens.
    Version: 1.0
    Author: Matt Wiebe
    Author URI: http://somadesign.ca/
    */

    /**
    * The smaller image is wrapped in a <noscript> tag so 1) it'll show up on non-JS browsers
    * and 2) it won't be partially downloaded on desktop browsers.
    *
    * JS-enabled browsers will sniff the breakpoint for which size of image to sub in
    * Be sure to regenerate thumbnails after starting to use
    * @link http://wordpress.org/extend/plugins/regenerate-thumbnails/
    *
    * Won't work very well inside [caption] shortcodes
    * <noscript> concept: @link http://somad.es/5D
    */

    class SD_Resonsive_Images {

    function init() {
    // this is the screen width at which we'll use the larger image
    // define it in your functions.php or wp-config.php to override
    if ( ! defined( 'MOBILE_FIRST_BREAKPOINT') ) {
    define( 'MOBILE_FIRST_BREAKPOINT', 480 );
    }
    // our image size
    add_image_size( 'mobile-first', MOBILE_FIRST_BREAKPOINT, MOBILE_FIRST_BREAKPOINT );

    add_filter( 'the_content', array( __CLASS__, 'responsive_images' ) );

    // ensure jQuery is ready for our stuff later
    wp_enqueue_script('jquery');
    add_action( 'wp_footer', array( __CLASS__, 'swap_images_js' ), 11 );
    }


    function responsive_images($content) {
    $regex = '/<img .* wp-image-[0-9]{1,10}.* \/?>/';
    return preg_replace_callback( $regex, array( __CLASS__, 'make_respnsive_image' ), $content );
    }

    function make_respnsive_image($image) {
    if ( is_array($image) ) {
    $image = array_shift($image);
    }
    preg_match('/wp-image-([0-9]{1,10})/', $image, $matches );
    if ( ! $matches || count($matches) < 2 ) {
    return $image;
    }
    $attachment = get_post($matches[1]);
    $small = wp_get_attachment_image_src( $attachment->ID, 'mobile-first' );
    $small_url = $small[0];

    // if it's the same image, just return it
    if ( false !== strpos($image, $small_url) ) {
    return $image;
    }

    // let's array up the atts
    $new = str_replace(array( '<img ', ' />', ' >' ), '', $image );
    $parts = preg_split( '/[\'"] /', $new );
    $atts = array();
    foreach ( $parts as $part ) {
    $part = explode('=', $part);
    $atts[ $part[0] ] = trim($part[1], '\'" ');
    }

    // No width/height for mobile first responsive
    if ( isset($atts['width']) ) {
    // let's not bother if it's already small-ish
    if ( $atts['width'] <= MOBILE_FIRST_BREAKPOINT ) {
    return $image;
    }
    unset($atts['width']);
    }
    if ( isset($atts['height']) ) unset($atts['height']);
    // I think title attributes on images suck. Goodbye
    if ( isset($atts['title']) ) unset($atts['title']);

    // move old src to data attribute, make small src default
    $atts['fullsrc'] = $atts['src'];
    $atts['src'] = $small_url;

    // put it back together
    $return = $img_atts = $wrapper_atts = '';

    foreach ( $atts as $att => $val ) {
    if ( 'fullsrc' !== $att )
    $img_atts .= $att . '="' . $val . '" ';
    $wrapper_atts .= 'data-' . $att . '="' . $val . '" ';
    }
    $return = "<img {$img_atts}/>";
    // we need to wrap in a span to prevent some occasionally janky behaviour
    // I'm looking at you, iOS
    $return = "<span class=\"responsivize\" {$wrapper_atts}><noscript>{$return}</noscript></span>";
    return $return;
    }

    function swap_images_js() { ?>
    <script>
    var MOBILE_FIRST_BREAKPOINT = <?php echo MOBILE_FIRST_BREAKPOINT; ?>;
    jQuery(document).ready(function($){
    var useFull = ( window.screen.width > MOBILE_FIRST_BREAKPOINT );
    $(".responsivize").each(function(){
    var me = $(this),
    data = me.data()
    if ( useFull ) {
    data.src = data.fullsrc
    }
    delete data.fullsrc
    $("<img />", data).insertBefore(me)
    me.remove()
    })
    })
    </script>
    <?php
    }

    }

    add_action( 'init', array( 'SD_Resonsive_Images', 'init') );