Gazley Posted January 18, 2016 Share Posted January 18, 2016 Hi there, Is there a standard approach in PW to building image markup with (at least) srcset and sizes? I saw the module by conclurer: Srcset Image Textformatter However, there are some use-cases that this doesn't cover and I'm not sure whether this module has "ran out of steam" (not much activity on the support thread or Github repo) ? Maybe PW 3 will provide this support in core? Any ideas or thoughts would be appreciated. Many thanks! Link to comment Share on other sites More sharing options...
ukyo Posted January 18, 2016 Share Posted January 18, 2016 (edited) On my side i prepared a function for srcset and <picture> tag creation. Function output look like : <picture> <!--[if IE 9]> <video style='display: none;'> <![endif]--> <source srcset='data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==' data-srcset='/site/assets/files/1058/terra-nova-001.404x270.jpg' media='(max-width: 479px)' /> <source srcset='data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==' data-srcset='/site/assets/files/1058/terra-nova-001.692x462.jpg' media='(max-width: 767px)' /> <source srcset='data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==' data-srcset='/site/assets/files/1058/terra-nova-001.427x285.jpg' media='(max-width: 959px)' /> <!--[if IE 9]> </video> <![endif]--> <img src='data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==' data-srcset='/site/assets/files/1058/terra-nova-001.630x421.jpg' alt='terra-nova-001' class="lazyload uk-width-1-1" /> </picture> Here are my functions : /** /** * Generate Attributes Array or String * * @param $item * @return string */ function buildAttrs($item) { $attributes = ""; // echo "<pre>Key : " . print_r($item, true) . "</pre>"; if(array_key_exists('attributes', $item) && is_array($item['attributes'])) { foreach($item['attributes'] as $key => $attr) { $attributes .= ' ' . $key . '="' . $attr . '"'; } } return $attributes; } /** * * @param $image * @param $key * @param $options * @return string */ function buildSrcAndSrcset($image, $key, $options) { $return = ''; // echo "<pre>Key : {$key}, " . print_r($options, true) . "</pre>"; if(!empty($options[$key]) && !empty($options[$key]['sets']) && is_array($options[$key]['sets'])) { $x=1; $countSets = count($options[$key]['sets']); $sets = ""; foreach($options[$key]['sets'] as $k => $rules) { $y=$x++; $separator = ($y != $countSets) ? ", " : ""; if(!is_array($rules) && $rules == 'original') { $static_url = static_url($image->url); $sets .= "{$static_url} {$key}w{$separator}"; } elseif(isset($rules['width']) || isset($rules['height'])) { $size = imageResize($image, $rules); if(!is_null($size)) { $sets .= "{$size['url']} {$size['width']}w{$separator}"; } } } if($sets != "") $return = " {$key}='{$sets}'"; } elseif(!empty($options[$key]) && !empty($options[$key]['method']) && is_array($options[$key]['method'])) { $img = imageResize($image, $options[$key]['method']); if(!is_null($img)) $return = " {$key}='{$img['url']}'"; } elseif(!empty($options[$key]) && is_string($options[$key])) { $return = " {$key}='{$options[$key]}'"; } return $return; } /** * Image : Create <img /> tag with attributes and responsive lazyload option * * @param $image * @param array $options * @return string */ function image($image, $options = array(), $lightbox=FALSE) { $return = ""; // Alt attribute $alt = ($image->description != '') ? $image->description : pathinfo($image->filename, PATHINFO_FILENAME); $alt = " alt='{$alt}'"; if(array_key_exists('picture', $options) && is_array($options['picture'])) { $picture = $options['picture']; // Set Attributes $attributes = ""; if(array_key_exists('attributes', $picture)) { $attributes = buildAttributes($picture['attributes']); } $return .= "\n<picture{$attributes}>"; if(array_key_exists('source', $options['picture']) && is_array($options['picture']['source'])) { $return .= "\n\t<!--[if IE 9]><video style='display: none;'><![endif]-->"; $sources = $options['picture']['source']; foreach($sources as $key => $source) { $attrSrc = buildSrcAndSrcset($image, 'src', $source); $attrSrcset = buildSrcAndSrcset($image, 'srcset', $source); $attrDataSrcset = buildSrcAndSrcset($image, 'data-srcset', $source); $attributes = buildAttrs($source); $attrMedia = " media='{$key}'"; $return .= "\n\t\t<source{$attrSrc}{$attrSrcset}{$attrDataSrcset}{$attributes}{$attrMedia} />"; } $return .= "\n\t<!--[if IE 9]></video><![endif]-->"; } if(array_key_exists('img', $options['picture']) && is_array($options['picture']['img'])) { $img = $options['picture']['img']; $attrSrc = buildSrcAndSrcset($image, 'src', $img); $attrSrcset = buildSrcAndSrcset($image, 'srcset', $img); $attrDataSrcset = buildSrcAndSrcset($image, 'data-srcset', $img); $attributes = buildAttrs($img); $return .= "\n\t<img{$attrSrc}{$attrSrcset}{$attrDataSrcset}{$alt}{$attributes} />"; } $return .= "\n</picture>"; } elseif(array_key_exists('img', $options) && is_array($options['img'])) { $img = $options['img']; $attrSrc = buildSrcAndSrcset($image, 'src', $img); $attrSrcset = buildSrcAndSrcset($image, 'srcset', $img); $attrDataSrcset = buildSrcAndSrcset($image, 'data-srcset', $img); $attributes = buildAttrs($img); $return .= "\n<img{$attrSrc}{$attrSrcset}{$attrDataSrcset}{$alt}{$attributes} />"; } else { $src = " src='" . static_url($image->url) . "'"; $width = " width='{$image->width}'"; $height = " height='{$image->height}'"; // Set Attributes $attributes = ""; if(array_key_exists('attributes', $options)) { $attributes = buildAttributes($options['attributes']); } $return .= "\n<img{$src}{$width}{$height}{$alt}{$attributes} />"; } if(isset($lightbox) && $lightbox != FALSE) { $page = wire('page'); $title = ($image->description != "") ? $image->description : $page->title; $overlayEffect = (!is_bool($lightbox) && $lightbox != '') ? " " . $lightbox : " uk-overlay-fade"; $return = "\n<figure class='uk-overlay uk-overlay-hover'> \n\t{$return} \n\t<div class='uk-overlay-panel uk-overlay-background{$overlayEffect}'></div> \n\t<div class='uk-overlay-panel uk-overlay-icon{$overlayEffect}'></div> \n\t<a class='uk-position-cover' href='{$image->url}' title='{$title}' data-uk-lightbox=\"{group:'{$page->name}'}\"><span class='uk-hidden'>{$title}</span></a> \n</figure>"; } return $return; } /** * Resize Image * * @param $image * @param array $method * @return array|null */ function imageResize($image, $method=array()) { $alt = ($image->description != '') ? $image->description : pathinfo($image->filename, PATHINFO_FILENAME); if(isset($method['type']) && isset($method['width']) || isset($method['height'])) { // Set Resize Options if(isset($method['options'])) $options = $method['options']; else $options = wire('config')->imageSizerOptions; if($method['type'] === 'size' && isset($method['width']) && isset($method['height'])) { $size = $image->size($method['width'], $method['height'], $options); } elseif($method['type'] === 'width' && isset($method['width'])) { $size = $image->width($method['width'], $options); } elseif($method['type'] === 'height' && isset($method['height'])) { $size = $image->height($method['height'], $options); } else { $size = null; } if(!is_null($size)) { return array( 'url' => static_url($size->url), 'width' => $size->width, 'height' => $size->height, 'alt' => $alt ); } } elseif(is_null($method)) { return array( 'url' => static_url($image->url), 'width' => $image->width, 'height' => $image->height, 'alt' => $alt ); } return null; } /** * Return url with static url * * @param string $url * @return string */ function static_url($url="") { $config = wire('config'); if($config->debug === false && isset($config->static_url) && $config->static_url != "") { $static_url = $config->static_url; } else { $static_url = ""; } return $static_url . $url; } I set responsive sizes on my config file : /** * Responsive Image Options */ $responsiveSizes = array( 'small' => '480', 'medium' => '768', 'large' => '960', 'xlarge' => '1220' ); $config->resSmall = "(max-width: " . ($responsiveSizes['small']-1) . "px)"; $config->resMedium = "(max-width: " . ($responsiveSizes['medium']-1) . "px)"; $config->resLarge = "(max-width: " . ($responsiveSizes['large']-1) . "px)"; $config->resXlarge = "(min-width: {$responsiveSizes['xlarge']}px)"; And I created a file (including this file inside my init.php file) that file have responsive image sizes like : /** * Template --Villa List-- */ $respImgOptions['villa']['list'] = array( 'picture' => array( 'source' => array( $config->resSmall => array( 'srcset' => 'data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==', 'data-srcset' => array( 'method' => array( 'type' => 'size', 'width' => 404, 'height' => 270 ) ) ), $config->resMedium => array( 'srcset' => 'data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==', 'data-srcset' => array( 'method' => array( 'type' => 'size', 'width' => 692, 'height' => 462 ) ) ), $config->resLarge => array( 'srcset' => 'data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==', 'data-srcset' => array( 'method' => array( 'type' => 'size', 'width' => 427, 'height' => 285 ) ) ) ), 'img' => array( 'src' => 'data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==', 'attributes' => array( 'class' => 'lazyload uk-width-1-1' ), 'data-srcset' => array( 'method' => array( 'type' => 'size', 'width' => 630, 'height' => 421 ) ) ) ) ); And after all done calling images from page like : // on here you need to send single PageImage ! $img = image($page->image->first(), $config->respImgOptions['villa']['list']); Like this usage if you have https://github.com/aFarkas/lazysizes and https://github.com/aFarkas/lazysizes/tree/gh-pages/plugins/respimg every thing will work well ! Edited January 18, 2016 by ukyo 10 Link to comment Share on other sites More sharing options...
horst Posted January 18, 2016 Share Posted January 18, 2016 @ukyo: this looks very well. I have bookmarked this post because I allready use lazysizes and respimg in two projects, but I think I haven't it that well organized as you have. Next possibilty I have time for it, I will compare mine with yours and update / reorganize mine where needed. Many thanks for sharing! Link to comment Share on other sites More sharing options...
Gazley Posted January 18, 2016 Author Share Posted January 18, 2016 Hey @ukyo, Thanks for you great reply! Just out of interest, where are the functions buildSrcAndSrcset and buildAttrs found? Cheers! Link to comment Share on other sites More sharing options...
ukyo Posted January 18, 2016 Share Posted January 18, 2016 sorry also i updated my first reply /** * Generate Attributes Array or String * * @param $item * @return string */ function buildAttrs($item) { $attributes = ""; // echo "<pre>Key : " . print_r($item, true) . "</pre>"; if(array_key_exists('attributes', $item) && is_array($item['attributes'])) { foreach($item['attributes'] as $key => $attr) { $attributes .= ' ' . $key . '="' . $attr . '"'; } } return $attributes; } /** * * @param $image * @param $key * @param $options * @return string */ function buildSrcAndSrcset($image, $key, $options) { $return = ''; // echo "<pre>Key : {$key}, " . print_r($options, true) . "</pre>"; if(!empty($options[$key]) && !empty($options[$key]['sets']) && is_array($options[$key]['sets'])) { $x=1; $countSets = count($options[$key]['sets']); $sets = ""; foreach($options[$key]['sets'] as $k => $rules) { $y=$x++; $separator = ($y != $countSets) ? ", " : ""; if(!is_array($rules) && $rules == 'original') { $static_url = static_url($image->url); $sets .= "{$static_url} {$key}w{$separator}"; } elseif(isset($rules['width']) || isset($rules['height'])) { $size = imageResize($image, $rules); if(!is_null($size)) { $sets .= "{$size['url']} {$size['width']}w{$separator}"; } } } if($sets != "") $return = " {$key}='{$sets}'"; } elseif(!empty($options[$key]) && !empty($options[$key]['method']) && is_array($options[$key]['method'])) { $img = imageResize($image, $options[$key]['method']); if(!is_null($img)) $return = " {$key}='{$img['url']}'"; } elseif(!empty($options[$key]) && is_string($options[$key])) { $return = " {$key}='{$options[$key]}'"; } return $return; } 2 Link to comment Share on other sites More sharing options...
ukyo Posted January 18, 2016 Share Posted January 18, 2016 @ukyo: this looks very well. I have bookmarked this post because I allready use lazysizes and respimg in two projects, but I think I haven't it that well organized as you have. Next possibilty I have time for it, I will compare mine with yours and update / reorganize mine where needed. Many thanks for sharing! Thanks @horst, if you see my mistakes and no need things or any useful things let me know please 1 Link to comment Share on other sites More sharing options...
Gazley Posted January 18, 2016 Author Share Posted January 18, 2016 Hi @ukyo, I wondered whether you had an example of some the options that you pass to the image function. Also, could you comment on the lightbox parameter too? Many thanks! Link to comment Share on other sites More sharing options...
ukyo Posted January 18, 2016 Share Posted January 18, 2016 It for uikit lightbox component, resizing image and adding lightbox link automatically with overlay effect. If you don't use uikit you can remove these codes from function or you can customize them for your needs. I dind't modify my code, directly shared them with community and you can take it as example and you can modify codes or you can create a function as your needs. // Without lightbox $img = image($page->image->first(), $config->respImgOptions['villa']['list']); // With lightbox, its enought to send "true" or "overlay" class, after set responsive image settings $img = image($page->image->first(), $config->respImgOptions['villa']['list'], true); Lightbox example output : <figure class='uk-overlay uk-overlay-hover'> <picture> <!--[if IE 9]> <video style='display: none;'> <![endif]--> <source srcset='data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==' data-srcset='/site/assets/files/1058/terra-nova-003.344x212.jpg' media='(max-width: 479px)' /> <source srcset='data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==' data-srcset='/site/assets/files/1058/terra-nova-003.309x190.jpg' media='(max-width: 767px)' /> <source srcset='data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==' data-srcset='/site/assets/files/1058/terra-nova-003.265x164.jpg' media='(max-width: 959px)' /> <!--[if IE 9]> </video> <![endif]--> <img src='data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==' data-srcset='/site/assets/files/1058/terra-nova-003.290x180.jpg' alt='terra-nova-003' class="lazyload uk-responsive-width uk-overlay-spin" /> </picture> <div class='uk-overlay-panel uk-overlay-background uk-overlay-fade'></div> <div class='uk-overlay-panel uk-overlay-icon uk-overlay-fade'></div> <a class='uk-position-cover' href='/site/assets/files/1058/terra-nova-003.jpg' title='Terra Nova' data-uk-lightbox="{group:'terra-nova'}"> <span class='uk-hidden'>Terra Nova</span> </a> </figure> 3 Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now