Jump to content


  • Posts

  • Joined

  • Last visited

  • Days Won


nbcommunication last won the day on January 13 2021

nbcommunication had the most liked content!

1 Follower

Profile Information

  • Gender
    Not Telling
  • Location
    Lerwick, Shetland

Recent Profile Visitors

The recent visitors block is disabled and is not being shown to other users.

nbcommunication's Achievements

Sr. Member

Sr. Member (5/6)




Community Answers

  1. Hi @snck, Thanks for the feedback and the great example! Unfortunately the issue you've raised is more of an issue with how Pageimage::render() is implemented. Adding 'width' or 'height' options is interpreted as a request to resize the Pageimage, which is not what we want in PageimageSource::render(). The default markup does not include width and height attributes, so the only way to add them without resizing the image is to provide them in a specified markup string. I have a hook in an internal development module which sets a default markup string with these attributes: <?php // Pageimage:render $this->addHookBefore('Pageimage::render', function(HookEvent $event) { $markup = $event->arguments(0); $options = $event->arguments(1); if(!is_string($markup)) { $options = $markup; $markup = '<img src="{url}" alt="{alt}" width="{width}" height="{height}">'; } $event->arguments(0, $markup); $event->arguments(1, $options); }); This means I can generally call render() without any options. If your example is something you are doing repeatedly, you could utilise a similar strategy in site/ready.php: <?php // /site/ready.php $wire->addHookBefore('Pageimage::render', function(HookEvent $event) { $markup = $event->arguments(0); $options = $event->arguments(1); if(!is_string($markup)) $options = $markup; if($options['masonry'] ?? false) { // a custom option $img = $event->object; $thumb = $img->width(480); $markup = "<img src='$thumb->url' alt='{alt}' class='{class}' width='$thumb->width' height='$thumb->height'>"; $options = array_merge([ 'picture' => true, 'srcset' => [360, 480, 640, 800], 'sizes' => '(max-width: 579px) calc(100vw - (2 * 34px)), (min-width: 580px) and (max-width: 767px) calc(50vw - (1.5 * 34px)), (min-width: 768px) and (max-width: 1199px) calc(33.3333vw - (1.33 * 34px)), (min-width: 1200px) and (max-width: 1499px) calc(25vw - (1.25 * 34px)), (min-width: 1500px) calc(20vw - (1.2 * 34px))', 'class' => 'teaser-img proportional', 'alt' => $img->description, ], $options); } $event->arguments(0, $markup); $event->arguments(1, $options); }); // In your code $img->render([ 'masonry' => true, 'class' => 'overriding-the-default-class', 'alt' => __('Overriding the default alt text'), ]); // Not tested!!! Cheers, Chris
  2. Hi @bernhard, Honestly, I find the way in which browsers actually implement srcset and sizes to be really confusing. In the previous PageimageSrcset I included a bit of javascript for debugging, as I found it was sometime difficult to even tell which image was being used (if they were just different width variations). What complicates debugging is that the browser will use the largest image it has in the cache, so if you've loaded the page at desktop width and then try to see how it'll respond at a smaller screen size, it will still display the larger image. What happens if you add 1280 2x into the set? Cheers, Chris
  3. No, it would terminate at 4096. Because this width is greater than the original, it won't generate a variation and it'll output the original as the source for 4096w. It then wouldn't make sense to output the original as the source for 2048w as it has already been used. This makes more sense in the smallest to largest context: 256 - variation generated 512 - variation generated 1024 - variation generated 2048 - width > than original, original used 4096 - set not output as original already used for 2048w. I hope that makes sense. Cheers, Chris
  4. Hi @uiui, I've added in this option and released v1.0.4. From the README: Use for all dimensions? If enabled, a set rule will be used regardless of whether it is wider or higher than the dimensions of the original image. To use this on a srcset call, enable the allSets option: $srcset = $image->srcset('4096, 2048, 1024, 512, 256', [ 'allSets' => true, ]); // If passing an image 2000px in width, the above would return a srcset with set rules for each given width // Without 'allSets' enabled, the srcset generation would terminate at 4096w I hope that is useful! Cheers, Chris
  5. Hi @uiui, Variations are only generated and used for sizes smaller than the original. When it reaches a dimension where the image does not need to be resized, it 'completes' the generation process. Running your examples on an image 2048px wide gives me: /site/assets/files/1033/very_large_array_clouds.webp 4096w/site/assets/files/1033/very_large_array_clouds.1920x0-srcset.webp 1920w, /site/assets/files/1033/very_large_array_clouds.1600x0-srcset.webp 1600w, /site/assets/files/1033/very_large_array_clouds.1280x0-srcset.webp 1280w, /site/assets/files/1033/very_large_array_clouds.980x0-srcset.webp 980w, /site/assets/files/1033/very_large_array_clouds.480x0-srcset.webp 480w, /site/assets/files/1033/very_large_array_clouds.webp 4096w This is definitely a quirk of the module's implementation that I hadn't considered - all the srcset examples I referred to during development had the sources ordered smallest to largest - and I don't think it is something I can sort in the default implementation. Perhaps I could add an option to disable the automatic completion e.g. 'Generate variations for all srcset dimensions?' Would this be useful for you? Cheers, Chris
  6. We really like the ability to add redirects via the page editor, but it is annoying that this functionality is only available to superusers. We often have clients asking us to add a 'short url' redirect for a page (e.g. /jobs -> /about/work/jobs) when it really is something they should be able to do themselves. To solve this problem, we've created ProcessPageRedirects. It does two things: Creates a page (Pages > Redirects) which lists all the visible pages to that user and the number of redirects (among other things) Allows them to manage the redirects for pages they can edit The redirects editor is the same one the superuser gets when editing the page. I hope this is useful, let me know here if you come across any issues with it.
  7. Hi @Luigi, This is something that happens to some of our websites, some more info here: I've never been able to solve the issue, although as it is infrequent and has always passed before I notice the email error notifications, I've never really spent a lot of time trying to replicate and debug it. In the linked thread it was said that disabling Tracy Debugger worked - I don't have this on the sites where this error tends to happen, but if you do perhaps that will solve it. Cheers, Chris
  8. Hi @t0b1, Thanks, I must've missed this when writing up the README. That's it added now. Cheers, Chris
  9. Hello, I'll not be actively maintaining this module going forward as we are no longer using it, instead implementing a CSP via a Header set in .htaccess. This is preferable for many reasons, and I expect that at some point in the future a CSP set in a <meta> tag, while still valid, will be penalised in audit tools. After a bit of trial and error I discovered the solution to setting a CSP in .htaccess, without it affecting the admin: <IfModule mod_headers.c> # If not the PW admin <If "! %{QUERY_STRING} =~ /youradminurl/"> # Content Security Policy Header set Content-Security-Policy "default-src 'self'" </If> </IfModule> The If conditionals are a feature of Apache 2.4 which I'd assume most are using. I believe there are other approaches to conditionals for 2.2. For reporting, we're going to be using report-uri.com. In conclusion, the snippet in .htaccess looks something like this: <IfModule mod_headers.c> # If not the PW admin <If "! %{QUERY_STRING} =~ /adminurl/"> Header set Referrer-Policy "no-referrer-when-downgrade" Header set Report-To "{\"group\":\"default\",\"max_age\":31536000,\"endpoints\":[{\"url\":\"https://accountname.report-uri.com/a/d/g\"}],\"include_subdomains\":true}" Header set Content-Security-Policy "default-src 'self'; ... base-uri 'self'; frame-ancestors 'self'; report-to default; report-uri https://accountname.report-uri.com/r/d/csp/enforce" </If> </IfModule> More information on report-uri/report-to here: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/report-uri If anyone wishes to take on responsibility for this module, please let me know here. I would recommend however that you look at using the .htaccess implementation outlined above. Cheers, Chris
  10. Just implemented this in combination with a $cache-ing of the $pages->find() query. Lightning fast. if(file_exists($file) && filemtime($file) > $page->modified) { Would it not be $item->modified? Cheers, Chris
  11. Today I needed to implement a background image with sources, using the new UIkit Image component implementation: https://getuikit.com/docs/image#picture-sources PageimageSource doesn't do this out of the box, but I found I neat solution, which I thought I'd share: <?php // $bannerImage = Pageimage; preg_match_all('<source\ssrcset="(.*?)"\ssizes="(.*?)"\stype="(.*?)">', $bannerImage->render(), $matches); $sources = []; foreach($matches as $index => $match) { if(!$index) continue; foreach($match as $i => $v) { if(!isset($sources[$i])) { $sources[$i] = []; } $sources[$i][[ 'srcset', 'sizes', 'type', ][$index - 1]] = $v; } } echo '<div class="uk-background-cover" sources="' . $sanitizer->entities(json_encode(array_values($sources))) . '" data-src="' . $bannerImage->url . '" data-uk-img></div>'; This assumes that the render() function is returning a <picture> element. Cheers, Chris
  12. Hi @neophron, Apologies for the late response. This is a bit of a cop-out answer, but there are no prescriptions for srcset/sizes. What is right is whatever works best for your use case. The only way to get there is to experiment. That said, perhaps this is what you should do? <?php echo "<img class='photo' src='{$slide->size(760, 0, $options)->url}' srcset='{$slide->url} 2x' alt='{$slide->description}' loading='lazy'>"; Regarding the 'orientation: portrait' sizes attribute - this isn't to do with the image's orientation, it is the device orientation. You can use it to specify a size profile for this e.g. <?php // Render an image using custom set rules and sizes // These rules will render 'portrait' versions of the image for tablet and mobile // Note the advanced use of the `srcset` option passing both `rules` and image `options` // WebP is disabled // Picture is disabled echo $image->render([ 'srcset' => [ 'rules' => '320x569, 640x1138, 768x1365, 1024, 1366, 1600, 1920', 'options' => [ 'upscaling' => true, 'hidpi' => true, ], ], 'sizes' => '(orientation: portrait) and (max-width: 640px) 50vw', 'picture' => false, ]); // <img src='image.jpg' alt='' srcset='image.320x569-srcset-hidpi.jpg 320w, image.640x1138-srcset-hidpi.jpg 640w, image.768x1365-srcset-hidpi.jpg 768w, image.1024x0-srcset-hidpi.jpg 1024w, image.1366x0-srcset-hidpi.jpg 1366w, image.1600x0-srcset-hidpi.jpg 1600w, image.jpg 1920w' sizes='(orientation: portrait) and (max-width: 768px) 50vw' loading="lazy"> I'm not 100% myself on how the above actually works, but it provides '2x' portrait images for small portrait devices e.g. mobile. If there's one bit of advice I'd give with srcset, it is keep it simple! I hope that helps. Cheers, Chris
  13. Hi @Stefanowitsch, Sorry for the late reply. I've had a quick look this morning and for me the variations are being regenerated correctly after a change of focus, but the browser's image cache is the issue - the filename doesn't change after the focus change so it just displays the old one it has cached. Hopefully the brief screencast attached will demonstrate. I'm not sure I can remedy this - will have a look when I can to see what's been suggested elsewhere for the issue. Cheers, Chris Screen Recording 2021-11-29 at 08.35.37.mov
  14. Hi @Stefanowitsch, I'm always using UIkit when developing so either make use of the Image component which has background image srcset functionality, or if using the <picture> element functionality of this module, I use the Cover component. Cheers, Chris
  • Create New...