Jump to content

Search the Community

Showing results for 'webp'.

  • Search By Tags

    Type tags separated by commas.
  • Search By Author

Content Type


Forums

  • Welcome to ProcessWire
    • News & Announcements
    • Showcase
    • Wishlist & Roadmap
  • Community Support
    • Getting Started
    • Tutorials
    • FAQs
    • General Support
    • API & Templates
    • Modules/Plugins
    • Themes and Profiles
    • Multi-Language Support
    • Security
    • Jobs
  • Off Topic
    • Pub
    • Dev Talk

Product Groups

  • Form Builder
  • ProFields
  • ProCache
  • ProMailer
  • Login Register Pro
  • ProDrafts
  • ListerPro
  • ProDevTools
  • Likes
  • Custom Development

Find results in...

Find results that contain...


Date Created

  • Start

    End


Last Updated

  • Start

    End


Filter by number of...

Joined

  • Start

    End


Group


AIM


MSN


Website URL


ICQ


Yahoo


Jabber


Skype


Location


Interests

  1. A while back I added webp support to arthistoryproject.com, but didn't see a ton of image size improvement. Then today I read this post by the genius horst, and realized I could tweak webp quality settings in config.php. I've made some changes, and new webp renders are WAY smaller. Fantastic! But now I'm wondering if there's a way to programmatically delete/overwrite previously rendered image variations, either site-wide or page-by-page. But of course, only once per page/image. Does that make sense? Thanks so much for any ideas! Reed
  2. This week we’ll take a look at 3 different WEBP image strategies that you can use in ProcessWire 3.0.132+. Then we’ll dive into a major update for the Google Client API module, and finish up by outlining some useful new updates in FormBuilder— https://processwire.com/blog/posts/webp-images-and-more/
  3. I have played with a .htaccess only solution to serve WEBP instead of JPEGs or PNGs. This way you can - leave your existing template markup untouched, and the apache_rewrite will - detect if the browser supports WEBP - if a WEBP copy is available for a JPEG or PNG image. Locally it's working out nicely! ? This markup automatically serves a WEBP copy to all browsers that support it: $options = ['webpAdd'=>true, 'webpQuality'=>90]; $image = $page->images->first()->size(300, 300, $options); // this will create a 300x300 Thumb for JPEGs and PNGs with an additional WEBP copy ?> <img src="<?=$image->src?>" alt="<?=$image->alt?>" /> <!-- this will serve the WEBP image to all Browsers that supports it, and the JPEG/PNG to other browsers --> AddType image/webp .webp <IfModule mod_rewrite.c> RewriteEngine On AddDefaultCharset UTF-8 ### Redirect regular PW JPEGs and PNGs to their WEBP image copies, ### if available and if the Browser supports WEBP: ## Does Browser accept WEBP images? RewriteCond %{HTTP_ACCEPT} image/webp ## Is it an existing file? RewriteCond %{REQUEST_FILENAME} -f ## Does a WEBP copy exist for it? RewriteCond %{DOCUMENT_ROOT}/$1$2$3/$4.webp -f ## With an added GET var or GET value of skiprewrite we do send the original JPEG or PNG RewriteCond expr "! %{QUERY_STRING} -strmatch '*skiprewrite*'" ## With an added GET var or GET value from the PW Page Editor, we do send the original JPEG or PNG RewriteCond expr "! %{QUERY_STRING} -strmatch 'nc=*'" ## Is it a regular PW JPEG or PNG image, stored under site/assets/files? RewriteRule ^(.*?)(site/assets/files/)([0-9]+)/(.*)\.(jpe?g|png)(.*)$ /$1$2$3/$4.webp [L] </IfModule> Adding a GET var or GET value with the string "skiprewrite" added to an image bypasses serving the WEBP copy in favour for the original variation. (Maybe useful for debug purposes!)
  4. @horst I use the code below in my template to generate different sizes of a cropped image: <source type="image/webp" srcset="<?= $page->image->getCrop("default")->width(450)->webp->url; ?> 1x, <?= $page->image->getCrop("default")->width(900)->webp->url; ?> 2x"> <source type="image/jpeg" srcset="<?= $page->image->getCrop("default")->width(450)->url; ?> 1x, <?= $page->image->getCrop("default")->width(900)->url; ?> 2x"> After I re-crop the image in the backend the variations of the jpeg version are regenerated, but the variations of the webp version are not regenerated/showed in the frontend. Is there a way to overwrite the webp variants after the image is re-cropped? Deleting all variations in the backend before re-cropping the image doesn't solve this issue. See also this post (not related to CroppableImage)
  5. @horst, thanks. I gave dev version 3.0.183 and RepeaterMatrix v5 a try. ✅ Deleting the JPG/PNG variations will delete all files within /assets/files/1134/. ❌ Deleting the webP variations will remove them from the variants list, however all files still remain in the /assets/files/1134/ directory. Maybe I am missed something in my RepeaterMatrix code. My markup code: <?php if(count($page->img_test)) { foreach($page->img_test as $image){ $imgsettings = array( 'quality' => 80, 'cropping' => 'southeast' ); $img_1920 = $image->size(1920, 1080, $imgsettings); $img_1600 = $image->size(1600, 0, $imgsettings); $img_500 = $image->size(500, 0, $imgsettings); echo " <picture> <source srcset='{$img_1920->webp->url}' loading='lazy' type='image/webp' alt='{$img_1920->description}' sizes='100vw' srcset='{$img_500->webp->url} 500w, {$img_1600->webp->url} 1600w, {$img_1920->webp->url} 1920w' class='canvas__fullsize-img'> <source srcset='{$img_1920->url}' loading='lazy' type='image/{$image->ext}' alt='{$img_1920->description}' sizes='100vw' srcset='{$img_500->url} 500w, {$img_1600->url} 1600w, {$img_1920->url} 1920w' class='canvas__fullsize-img'> <img src='{$img_1920->url}' loading='lazy' alt='{$img_1920->description}' sizes='100vw' srcset='{$img_500->url} 500w, {$img_1600->url} 1600w, {$img_1920->url} 1920w'> </picture>"; } }
  6. ProcessWire added WebP image support this year and many have been adopting it enthusiastically in existing projects. In this post we’ll look at a process used for migrating an existing website to use WebP images. We’ll cover everything from preliminary considerations to implementation and testing, with lots of tips and tricks along the way— https://processwire.com/blog/posts/webp-images-on-an-existing-site/
  7. Hello processwire world! Im having a little problem with getting my image in WEBP format. $image = $pages->get('/')->images->first(); echo $image->webp()->url();
  8. Yes, that is it. So simple! Thank you heaps. That will get me going. I did search in the forums and docs/tuts. Do you have good resources for me to follow through with delayed output with regards to making proper responsive images. On my list is this. 1. Define image sizes and upon upload have ProcessWire create those. a) Return the array of all created image urls. b) Ideally create webp versions of those images as well. For webp support I found this 2. In the end I would like to write a function that I can include in a region that will output proper responsive image syntax similar to this. <picture class="pic-id-578 projects-picture" ><source sizes="(min-width: 1700px) 469px, (min-width: 1200px) 27.71vw, (min-width: 780px) calc(50vw - 80px), (min-width: 640px) calc(50vw - 24px), calc(100vw - 32px)" srcset=" https://example.com/picture-640x427.webp 640w, https://example.com/picture-525x350.webp 525w, https://example.com/picture-425x284.webp 425w, https://example.com/picture-320x214.webp 320w, https://example.com/picture-240x160.webp 240w, https://example.com/picture-180x120.webp 180w " type="image/webp" /> <img class="lazyload" src="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==" data-src="https://example.com/picture-320x214.jpg" alt="Some useful alternative text" sizes="(min-width: 1700px) 469px, (min-width: 1200px) 27.71vw, (min-width: 780px) calc(50vw - 80px), (min-width: 640px) calc(50vw - 24px), calc(100vw - 32px)" data-srcset="https://example.com/picture-640x427.jpg 640w, https://example.com/picture-525x350.jpg 525w, https://example.com/picture-425x284.jpg 425w, https://example.com/picture-320x214.jpg 320w, https://example.com/picture-240x160.jpg 240w, https://example.com/picture-180x120.jpg 180w" /> </picture> Coming from WP I did write this function. <?php function responsive_picture($acf_image_array, $media_condition, $type) { // Get the global $theme_name_pagename variable global $theme_name_pagename; // var_export( $theme_name_pagename ); // Get the global $theme_name_category_slug variable global $theme_name_category_slug; // var_export( $theme_name_category_slug ); // Get the global $theme_name_custom_post_type_slug variable from archive.php global $theme_name_custom_post_type_slug; // var_export( $theme_name_custom_post_type_slug ); // Make an array where the sources for the image will be placed $sources = array(); // If the field for the post/page/cpt is filled then do stuff, otherwise don't if ($acf_image_array) { foreach ($acf_image_array['sizes'] as $image_size_key => $image_size_value) { if (preg_match('/^(\d+)$/', $image_size_key)) { if (preg_match('/-' . $image_size_key . 'x\d+\.(jpeg|jpg|png)$/i', $image_size_value)) { array_push( $sources, array( 'width' => $image_size_key, 'height' => $acf_image_array['sizes'][$image_size_key . '-height'], 'src' => $image_size_value, ) ); } } } // end foreach ( $acf_image_array['sizes'] as $image_size_key => $image_size_value ) // http://php.net/manual/en/function.array-reverse.php // $sources = array_reverse( $sources ); // return var_export( $sources ); // exit; $srcset = array(); foreach ($sources as $index => $source_values) { array_push($srcset, $source_values['src'] . ' ' . $source_values['width'] . 'w'); } $srcset = implode(', ', $srcset); // preg_replace .jpg with .webp // http://php.net/manual/en/function.preg-replace.php $srcset_webp = $srcset; $pattern = '/.jpg /'; $replacement = '.webp '; $srcset_webp = preg_replace($pattern, $replacement, $srcset_webp); // var_export($srcset_webp); // Depending on the post, page or custom post type, set the picture class accordingly if (null !== $theme_name_pagename) { // echo esc_html( $pagename ); print '<picture class="pic-id-' . esc_html($acf_image_array['id']) . ' page-' . esc_html($theme_name_pagename) . '-picture">'; } if (null !== $theme_name_category_slug) { // echo esc_html( $category_slug ); print '<picture class="pic-id-' . esc_html($acf_image_array['id']) . ' category-' . esc_html($theme_name_category_slug) . '-picture">'; } if (null !== $theme_name_custom_post_type_slug) { // var_export( esc_html( $post_type ) ); // var_export( $theme_name_custom_post_type_slug ); // https://codex.wordpress.org/Function_Reference/is_post_type_archive // Differentiate between single- and archive- if (is_post_type_archive($theme_name_custom_post_type_slug)) { // print 'is_post_type_archive'; print '<picture class="pic-id-' . esc_html($acf_image_array['id']) . ' archive-' . esc_html($theme_name_custom_post_type_slug) . '-picture">'; } else { print '<picture class="pic-id-' . esc_html($acf_image_array['id']) . ' single-' . esc_html($theme_name_custom_post_type_slug) . '-picture">'; } } else { // null === $theme_name_custom_post_type_slug // var_export( $theme_name_custom_post_type_slug ); $post_type = get_post_type(); if ('' !== $post_type && 'page' !== $post_type) { $post_type_data = get_post_type_object($post_type); $theme_name_custom_post_type_single_slug = $post_type_data->rewrite['slug']; // var_export( esc_html( 'single ' . $theme_name_custom_post_type_single_slug ) ); print '<picture class="pic-id-' . esc_html($acf_image_array['id']) . ' single-' . esc_html($theme_name_custom_post_type_single_slug) . '-picture">'; } } // This part of the function is for the webp file format START ;) print '<source '; // print 'sizes="' . esc_html( $media_condition . $viewport ) . '" '; // leave space between attributes print 'sizes="' . esc_html($media_condition) . '" '; // leave space between attributes print 'srcset="' . esc_html($srcset_webp) . '" '; // leave space between attributes print 'type="image/' . esc_html($type) . '">'; // either webp or jp2 and close <source> here // This part of the function is for the webp file format END ;) // Default loading // print '<img '; // print 'src="' . esc_html( $acf_image_array['sizes'][320] ) . '" '; // default image size leave space between attributes // print 'alt="' . esc_html( $acf_image_array['alt'] ) . '" '; // leave space between attributes // print 'sizes="' . esc_html( $media_condition ) . '" '; // leave space between attributes // print 'srcset="' . esc_html( $srcset ) . '">'; // close img tag here // print '</picture>'; // With lazysizes print '<img class="lazyload" src="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==" '; // leave space between attributes print 'data-src="' . esc_html($acf_image_array['sizes'][320]) . '" '; // default image size leave space between attributes Alternatively you can simply define a fallback src via the data-src attribute. print 'alt="' . esc_html($acf_image_array['alt']) . '" '; // leave space between attributes print 'sizes="' . esc_html($media_condition) . '" '; // leave space between attributes print 'data-srcset="' . esc_html($srcset) . '">'; // close img tag here print '</picture>'; } } In a template I would then go on to call that function for example with the following arguments. <?php // Get the array values for the field responsive_picture for the current post $responsive_picture_array = get_field( 'responsive_picture' ); responsive_picture( $responsive_picture_array, '(min-width: 1700px) 469px, (min-width: 1200px) 27.71vw, (min-width: 780px) calc(50vw - 80px), (min-width: 640px) calc(50vw - 24px), calc(100vw - 32px)', 'webp' ); ?> So that is my aim really that I am working towards. Once they all check out with this https://github.com/ausi/respimagelint I will be satisfied. Any sections in the forums/docs/tuts/api/recepies that you can think of, kindly fire away, thank you.
  9. Hi all users of the croppable image 3 fieldtype. I'm currently working on the module, or better I'm reworking the module to support webp copys like the core image field does. Unfortunately this will break backwards compatibility! ? My questions are, how should we handle this? Until now the crop variation has this sort of names: basename.ext becomes basename.-suffix.ext But with the new version, it looks like regular image variation files with a -suffix: basename.ext becomes basename.100x200-suffix.ext My current thoughts are along that lines: I create a new named module: CroppableImage4, that supports the same API as the CAI3 version plus an alternative method like getCrop4("suffix"), and I add some checking, when the CAI3 is installed / active, it only hooks the plus method, not the regular one. What do you think? Any suggestions, ideas, wishes? And how can we savely update from CAI3 to CAI4, for example with existing websites containing tons of images ❓ PS: Besides that, the new module now supports individual $options as array or selector strings. It generates 0x48 thumbs and webp copies by auto generation and by manually creating a crop. It removes all variations on every changes: changing a single image, changing or removing settings. It has input fields in modules config for webpAdd and webpQuality, so you can handle it different from the $config->imageSizerSettings, and you now can add individual options with every API call, like with the core image field: $pageimage->getCrop("suffix", $options)->url, or $pageimage->getCrop("suffix", $options)->webp->url. And some more minor tweaks.
  10. Ok so just stumbled into a website using Clouflare and the plain htaccess method doesn't seem to kick in, tried altering the url() method with a hook but stumbled back into the problem problem where it doesn't seem to work after applying size(). Anybody has some info on this? if($page->template != 'admin') { $wire->addHookAfter('Pageimage::url', function($event) { static $n = 0; $n = ++$n; if($n === 1){ $event->return = $event->object->webp()->url(); } $n--; }); }
  11. From a cursory search on the feasibility of this request: AVIF support does appear to be possible, but there would be more checks required to verify the server configuration meets the minimum requirements... ImageMagick supports AVIF as of v7.0.25 or later. PHP's GD library - as of PHP version 8.1 - supports AVIF when compiled with AVIF support, and also requires support via the libavif module. The libavif module must be version 0.8.2 or greater. At this point there might need to be a decision to determine how to handle image processing: Does a PNG get uploaded and processed and converted to both AVIF and WEBP, and then the smallest of the three options is what is served - or does the site admin decide one or the other (despite gains or losses)? Add in any variations and that's a lot of processing just for a single image.
  12. @horst as the image guru here, how feasible is it? I find that the lack of native AVIF support is an increasing performance issue for me. After more time using this new format, the compression gains are really quite amazing, and consistent (versus Webp). PW-powered sites — especially those that use lots of images such as photography / travel sites — could be much leaner and faster.
  13. Has anyone encountered such a problem? When you generate WEBP via $image->webp (IMagick Image Sizer enabled), files are created, but they are not valid. Accordingly, they do not open in the browser. These files look quite functional, but are not displayed. I can’t understand what kind of images can go bad during generation. I took one image, generated it in the same formats to get a working webp and a broken one. Google Chrome in the console displayed loading webp images, but did not display it. I downloaded both files. Comparing the files that I discovered a size mismatch for the generated WEBP files. File sizes differed by only 1 byte. screenshot. With the help of the HEX editor I looked at what was missing there. It turned out that during the generation of PHP does not append 1 byte to the end of the file, the file is not valid and Chrome can not display it. Working file; Broken file; Having studied the structure of WEBP a bit, I came to the conclusion that all live files always end with byte x00, in addition WEBP continues to work fine if you add any number of x00 to the end. You can check it yourself, everything works fine. $image = $page->images->first(); $resized = $image->size(1600, 960); $webp = $resized->webp->url; $file = fopen($webp, "a+"); fwrite($file, chr(0x00)); fclose($file);
  14. Hello to all mighty people and Happy New decade start. Wish you all the greatest goodness, joy and happiness. Well, and a lot of great code as well ? I've implemented WEBP images to optimize my soon to be released profile and by a lucky coincidence I discovered on my Mac that no images are showing when using the Safari. I thought that Apple would have embraced the idea by now when several other browsers have already done that but it seemed like I was wrong. I tested the .htaccess approach, however I could not make it working under Safari, so I decided to add a little function to my _functions.php: //WEBP Image Support function webp_support($imgURL) { // Check if the browser headers contain image/webp support if(strpos($_SERVER['HTTP_ACCEPT'], 'image/webp')) { // If yes, use the webp image url return $imgURL->webp; } else { //Else, show the original image url return $imgURL; } } After that, in every image call I do the following: <?php $img = $page->images->first // Call for the image location $image = webp_support($img->size(100,100)) // Used to size an image and convert it to WEBP //Image call in the markup echo "<img src='{$image->url}' alt='{$image->description}' >"; That seems to be working fine and show the WEBP format on Chrome, Opera and Firefox under MacOS/Windows/Linux but show the original image version under Safari. I did not test with the Windows version of Safari since it is a long time not updated version and it won't make much sense to support the newer format anyway. My question for you is if there is a simpler approach than my current to show WEBP images to the supported browsers and fallback to original If not?
  15. Why not? Why is webp treated only as variation and not as other "normal" image? I added this to /site/config.php: $config->hasWebpSupport = (strpos($_SERVER['HTTP_ACCEPT'], 'image/webp') !== false); $config->imageSizerOptions = array_merge($config->imageSizerOptions, array( 'webpAdd' => true )); And in my template: $img = $page->images->first(); $url = ($config->hasWebpSupport && $img->hasWebp) ? "urlWebp" : "url"; echo "<a href='{$img->$url}'>{$img->$url}</a>"; // this is actually php implementation of .htaccess rules Then I uploaded image.jpg and found out that webp is generated only for admin thumbs and not for my uploaded image. I don't want to call size() as my uploaded image is already the way I wanted, I just need webp. Is this unsupported situation? Why do we need webp as admin thumb? I added: $config->adminThumbOptions = array_merge($config->adminThumbOptions, array( 'webpAdd' => false )); and that fixed admin thumb webp creation, but of course there is no webp image. I then manually copied image.webp to the folder where image.jpg was uploaded and this time the image was correctly displayed in Chrome (that has webp support) and in IE (that lacks webp support). Maybe you could add another property to the image that would return the correct URL as in my template file? Should webp extension be listed in /wire/config.php on $config->fileContentTypes?
  16. Hello, We've recently been researching how to use ProcessWire in a horizontal scaling environment (multiple server instances using a load balanced, read replica databases), and ran an experiment using AWS Elastic Beanstalk. Getting read replica databases up and running was easy - it's built in to the core: https://processwire.com/blog/posts/pw-3.0.175/#how-to-use-it-in-processwire Using multiple server instances throws up one big problem: how to keep the filesystem on multiple instances in sync given that ProcessWire doesn't currently support using an external service (like s3 or EFS) as the filesystem. The solution that we came up with is to use various Cloudflare services (R2, Stream, Images) to serve file assets, and we've built a module to facilitate this: We're not using this in production yet, but our tests on EB were successful, and we're confident this will solve the main part of this problem. However the Cloudflare Images service is still quite new and there's still features to be rolled out (e.g. webP for flexible variants) so it can't be considered a complete solution yet. Additionally, we use ProCache and this presents an additional multi-instance problem - if the cache is cleared on one, how can we clear it on all? Our solution is to log clears in the database and use this to sync up clearing. We built another module: Again this worked well in our test, but isn't yet being used in production. The main purpose of this thread, aside from sharing these potential solutions, is to ask for and discuss other experiences of hosting ProcessWire in a horizontal scaling environment. What solutions did you come up with (if you want to share them) and are there other potential issues we maybe haven't thought about? Cheers, Chris
  17. Croppable Image 3 for PW 3.0.20+ Module Version 1.2.0 Sponsored by http://dreikon.de/, many thanks Timo & Niko! You can get it in the modules directory! Please refer to the readme on github for instructions. - + - + - + - + - + - + - + - + - + - NEWS - 2020/03/19 - + - + - + - + - + - + - + - + - + - There is a new Version in the pipe, that supports WebP too: - + - + - + - + - + - + - + - + - + - NEWS - 2020/03/19 - + - + - + - + - + - + - + - + - + - ------------------------------------------------------------------------- Updating from prior versions: Updating from Croppable Image 3 with versions prior to 1.1.7, please do this as a one time step: In the PW Admin, go to side -> modules -> new, use "install via ClassName" and use CroppableImage3 for the Module Class Name. This will update your existing CroppableImage3 module sub directory, even if it is called a new install. After that, the module will be recogniced by the PW updater module, what makes it a lot easier on further updates. ------------------------------------------------------------------------- For updating from the legacy Thumbnail / CropImage to CroppableImage3 read on here. -------------------------------------------------------------------------
  18. After a long time of concept work and a (not) so long time of development I launched a new website: https://www.marvin-wieckhorst.de Beware: German Language ? The whole site consists of 5 pages only. But the pages on this one are huge and full of different design elements. I'm trying to split it into interesting screenshots here but I think it's best if you visit the site and have a look at it by yourself. Here are some pictures, the tech talk section is below. Introduction with large images and catchy headlines on each page: Different teaser elements: Rocket animation with some vector images: Custom build ajax forms for the booking of the different training packages. These forms are presented in a modal. These forms are feeded directly from the backend via my custom form solution: Tech Talk: Well first a bit of design talk. Concept and design was the greater challenge than the later development. The customer had very clear expectations of what the different design elements should look like. So the real challenge was to get all the ideas right and put into a working design that does not look too overwhelming and convoluted in the end. PLUS it had to be responsive of course. Fitting giant design elements full of content that look awesome on a 2560 x 1440 display are difficult to handle on an iPphone display. Used Modules: I always try to use at few modules as possible. No pro fields were used on this one. Everything you see was build with the tools that Processwire offers out-of-the box or which is are in the core ? However some modules are just a must have in my opinion and there is what I used (and use in all my other projects aswell): - AOIM+ for bundling and compressing of JS+CSS - WireMail SMTP for all mail work - SEOMaestro - PageImageSource for WEBP image support - TracyDebugger For the frontend work I am using good ol' Bootstrap 4. Basically because of the excellent grid system / frontend forms and form validation / modals. Most else Bootstrap offers is not included in my build. All other frontend elements are custom. Plugins i used: - aos.js for all animations - lazysizes.js - owl carousel - masonry.js - niceselect for the custom dropdown menus inside the modal form There is also a video player included the the videos for this site are not produced yet. All together I get a really nice lighthouse score for the site: That's it for now. Have a nice week!
  19. I'm developing a site using HTMX to swap images in a gallery (it uses 'picture' element and 'srcset' so I didn't want to load all the markup at once) alongside PW regions and it works great. I haven't really encountered any problems or gymnastics -- but maybe my use-case is simple enough? <?php namespace ProcessWire; $imgMarkup = ''; $thumbMarkup = ''; $imgNum = 0; /** Build the gallery fragment (the bit that changes via HTMX) before output */ if ($page->gallery && $page->gallery->count() > 0) { $imgNum = $input->get('img', 'int', 0); // get image index number from GET var (AJAX and no-JS) $galleryImg = $page->gallery->eq($imgNum); // get the image from index // The image markup (actually rendered from a custom page class) $imgMarkup = '<picture> <source type="image/webp" srcset="..."> <img src="..." width=".." height="..." alt="..." srcset="..." sizes="..."> </picture>'; // If it is a ajax (HTMX) request, just echo the image markup and stop PW processing tyhe rest of the template. if ($config->ajax) { echo $imgMarkup; return $this->halt(); } /* When doing HTMX ajax swap, the rest of this template won't be rendered */ // Build the clickable thumbnails that do the swapping (simplified) foreach ($page->gallery as $item) { $thumbMarkup .= '<li><a href="..." hx-get="..."><img src="..." width="..." height="..." alt="..."></a></li>'; } } ?> <!-- The markup regions --> <pw-region pw-id="imageViewer"> <div class="image-wrapper"> <figure class="image-main-wrapper" id="mainImg"> <?=$imgMarkup?> </figure> <div class="image-thumbs-wrapper"> <!-- where the HTMX magic happens -- note the additional hx-headers, which allows PW's $config->ajax to work --> <ul class="image-thumbs" hx-trigger="click" hx-target="#mainImg" hx-swap="innerHTML" hx-headers='{"X-Requested-With": "XMLHttpRequest"}' > <?=$thumbMarkup?> </ul> </div> </div> </pw-region> <pw-region pw-id="pageContent" class="content-left">....</pw-region> <pw-region id="sidebarContent">...</pw-region> It just works... no need to faff with cancelling prepend/append templates etc, just rember to add the extra hx-header (also, you can do it once on a parent element), you don't need to add it to every call. I haven't ever tried, so I'm not 100%, but there might be a way to automatically add the header to every HTMX call with a bit of javascript in the header/footer. I feel all the tools are probably already there, but if there is an even easier way, though, that would be great.
  20. This is by design, because we have jpeg, gif and png as master images that can be used as originals for resizing, cropping, etc. and from the final variations optionally a webp can be created. The webp is called upon an regular page image object: $image->webp()->url. We would need a new Fieldtype or Inputfield for images only to collect and arrange images, without modifying methods. This could be able to support other file formats too. (TIFF, BMP or others maybe). But with the current image field, webp can't be handled as original image format. It's by design. Maybe an extention of the file field, that creates and displays a thumbnail additionally to the filename(s) would help?
  21. @matjazp If sending webp first is not possible to you, you may use the initial htaccess solution, what already worked for you, but with the redirect in the rewrite rule (R=301): AddType image/webp .webp <IfModule mod_rewrite.c> RewriteEngine On AddDefaultCharset UTF-8 ### Redirect regular PW JPEGs and PNGs to their WEBP image copies, ### if available and if the Browser supports WEBP: ## Does Browser accept WEBP images? RewriteCond %{HTTP_ACCEPT} image/webp ## Is it an existing file? RewriteCond %{REQUEST_FILENAME} -f ## Does a WEBP copy exist for it? RewriteCond %{DOCUMENT_ROOT}/$1$2$3/$4.webp -f ## With an added GET var or GET value of skiprewrite we do send the original JPEG or PNG RewriteCond expr "! %{QUERY_STRING} -strmatch '*skiprewrite*'" ## With an added GET var or GET value from the PW Page Editor, we do send the original JPEG or PNG RewriteCond expr "! %{QUERY_STRING} -strmatch 'nc=*'" ## Is it a regular PW JPEG or PNG image, stored under site/assets/files? RewriteRule ^(.*?)(site/assets/files/)([0-9]+)/(.*)\.(jpe?g|png)(.*)$ /$1$2$3/$4.webp [R=301,L] </IfModule>
  22. Please can someone test the .htaccess solution for WebP support in other environments? It is not much work, you don't have to install test branches or anything else. You only need to copy some lines into your .htaccess file and create a single webp image with the tool of your choice. Or if you don't have a converter tool for webp, simply make a copy of a jpeg and rename it with type .webp instead of .jpg. Steps to proceed: Copy the rewrite directives into the top of your .htaccess file Grab any image variation you already have embedded into a PW site, create a webp variation of and save it into the same assets/files/{ID}/ folder. (Maybe you want to invert the colors of the webp copy for better detection!) Create or go to a page where this image should be rendered as jpeg in a regular img tag, and look if the webp copy is served and displayed. (Don't forget to flush browser caches) The .htaccess code: My matched.php for debugging: Examples in Opera with opened Network-Tab, requesting one image that has a webp copy, and requesting the second image that do not have a webp copy: Same page in Opera and old IE11: If we have a wider test case, the chance that this can be embedded into the PW .htaccess file for optional usage (commented by default) would be helpful for many users to support webp with less effort on their sites!
  23. Do you have enabled the Imagemagick rendering engine in PW? You also may set strictly use the webp variation, also if the jpeg or png source is smaller in filesize. This is not often the case, but its possible. site/config.php: $config->webpOptions = array_merge($config->webpOptions, [ 'quality' => 84, 'useSrcExt' => false, // Use source file extension in webp filename? (file.jpg.webp rather than file.webp) 'useSrcUrlOnSize' => false, // Fallback to source file URL when webp file is larger than source? 'useSrcUrlOnFail' => true // Fallback to source file URL when webp file fails for some reason? ]);
  24. I understand thats it's crucial to save bandwith. That's why we have webP now, finally. But there is one line in PagefileExtra.php that delivers the normal image url instead of the webp version, if the webp filesize is larger. In my case and I think on other sites too this is an unwanted behaviour, as quality and colors are different if you compare a jpg and a webp image. To illustrate this I attached this image, where you can see that the first three products which are being delivered as JPGs because the filesize is smaller are really different looking than the next 3 which are in webp format , especially in the logo area. This is somewhat hard to see here, but on my development site it looks really bad and is a showstopper for me to use webp. What I ask for is an option to skip the filesize check and maybe the option to enter a treshold value when to use the smaller image. I created a github issue "make the fallback optional if pagefile->url is smaller than webp" EDIT: This is already possible if you use following code: //_init.php // output webp version for all $image->url() calls, skip SVG's if($page->template != 'admin') { $wire->addHookAfter('Pageimage::url', function($event) { static $n = 0; if(++$n === 1) { if (strstr($event->object->filename, '.svg') === false){ $event->return = $event->object->webp()->url(false); } } $n--; }); }
  25. I want to show you a project that I started developing in summer of 2022 and that went online in january 2023. Kulturhaus Wilster ("Arts Centre Wilster") https://www.kulturhauswilster.de The Kulturhaus Wilster - also called "Wilster's living room" by many visitors - is a socio-cultural center in the heart of Wilster. Wilster is a small City located north from Hamburg, germany. Despite the fact that this is a small venue they offer large amount of events. The events range all the way from concerts to theatre and everything inbetween! The old version of the site was a super simple WordPress website in a black-and-white only color scheme. In my opinion it did no justice to the very colorful program that the Kulturhaus offers so I tried my best to bring some color into the game. The whole website should have a shabby-chique look combined with clean, modern elements. The Homepage offers a preview of the next 8 upcoming events. A blog section is also included and the latest post is displayed next to the event calendar book as PDF download. The event pages offer a quick-reservation form (tickets are not sold online) and a quick look to the next upcoming events in the sidebar. The website features a large event calendar. It was a really nice exercise in using ProcessWires very own paging and selector features. Events can be searched and filtered by type (and month), too. All with a few lines of code only. For example "Look for events that take place in the future in a specific category" $events = $pages->find("select_event_cat.title~|%=$c, template=event, date_event>=today, sort=date_event, sort=time_from, limit=6"); Besides that the website features some colorful content pages with large images, galleries, textboxes and some teaser elements. The editors of the website are able to display all facets of the Kulturhaus this way. Tech Talk: Frontend Framework is Bootstrap 4.6 ProcessWire Modules used on this one are: - WireMail: SMTP (https://processwire.com/modules/wire-mail-smtp/) - SEO Maestro (https://processwire.com/modules/seo-maestro/) - All in one minify for asses (https://processwire.com/modules/all-in-one-minify/) - PageImageSource for webp image srcsets (https://processwire.com/modules/pageimage-source/) - JkPublishPages is used for time-controlled publishing of the blog posts. Please check out this module! Thanks @Juergen - @bernhards great RockFrontend was also used. In this particular project only the autorefresh feature (because this module was brandnew back then and development of the page was almost done). But even "only" using autorefresh makes it worth using it! Please have a look:
×
×
  • Create New...