nbcommunication Posted June 28, 2023 Author Share Posted June 28, 2023 Hi @Krlos, Yes, Pageimage::render() is for rendering image markup from a PageImage: https://processwire.com/api/ref/pageimage/render/ In your example above, the correct call would be: <section class="about-section pt-48 pb-48" style="background-image: url(<?= $page->images->url ?>); background-repeat: no-repeat; background-size: cover; background-position: center;"> Assuming that $page->images is a single Pageimage object and not multiple images. In this case it would be: <section class="about-section pt-48 pb-48" style="background-image: url(<?= $page->images->first->url ?>); background-repeat: no-repeat; background-size: cover; background-position: center;"> This of course doesn't use srcset in any way. Going on @Stefanowitsch's example above you would need to implement Lazysizes and Lazysizes beset and then add something like <section class="about-section pt-48 pb-48" style="background-image: url(<?= $page->images->first->url ?>); background-repeat: no-repeat; background-size: cover; background-position: center;" data-bgset="<?= $page->images->first->srcset ?>"> to your markup. I'm not familiar with Lazysizes though so doubt this is a working example. If you look through this thread you can see how I implemented srcset background images using UIkit's Image component. Cheers, Chris 1 Link to comment Share on other sites More sharing options...
snck Posted June 28, 2023 Share Posted June 28, 2023 On 6/22/2023 at 12:48 AM, snck said: Hi @nbcommunication, thanks for the quick reaction! The update fixed it for me. ? Cheers, Flo @nbcommunication I have to correct: The update fixed it in one specific case. I still have the problem in another place: $img->render( [ 'picture' => true, 'srcset' => [ 'rules' => ['800x400', '1600x800'], 'options' => [ 'upscaling' => true, ], ], 'allSets' => true, 'sizes' => '(max-width: 900px) 100vw, ((min-width: 901px) and (max-width: 1200px)) 67vw, ((min-width: 1201px) and (min-width: 1201px)) 50vw', 'class' => 'hero-img', 'alt' => "...", 'markup' => "<img src='".$img->size(800, 400)->url."' alt='{alt}' class='{class}' width='".$img->size(800, 400)->width."' height='".$img->size(800, 400)->height."'>", ] ) leads to this markup: <picture> <source srcset="FILENAME.800x400-srcset.webp 800w, FILENAME.webp 1600w" sizes="(max-width: 900px) 100vw, ((min-width: 901px) and (max-width: 1200px)) 67vw, ((min-width: 1201px) and (min-width: 1201px)) 50vw" type="image/webp"> <source srcset="FILENAME.800x400-srcset.jpg 800w, FILENAME.jpg 1600w" sizes="(max-width: 900px) 100vw, ((min-width: 901px) and (max-width: 1200px)) 67vw, ((min-width: 1201px) and (min-width: 1201px)) 50vw" type="image/jpeg"> <img src="FILENAME.800x400.jpg" alt="..." class="hero-img" width="800" height="400" loading="lazy"> </picture> The intrinsic dimensions of the image are 1080x721. I am really curious why the update worked in one place and not in the other. Do you need more information to investigate? Link to comment Share on other sites More sharing options...
nbcommunication Posted June 28, 2023 Author Share Posted June 28, 2023 Hi @snck, The approach here seems odd to me but I'm probably misunderstanding the use case. I'd do: <?php $img->size(800,400)->render( [ 'picture' => true, 'srcset' => [ 'rules' => ['800x400', '1600x800'], 'options' => [ 'upscaling' => true, ], ], 'allSets' => true, 'sizes' => '(max-width: 900px) 100vw, ((min-width: 901px) and (max-width: 1200px)) 67vw, ((min-width: 1201px) and (min-width: 1201px)) 50vw', 'class' => 'hero-img', 'alt' => "...", 'markup' => "<img src={src} alt='{alt}' class='{class}' width={width} height={height}>", ] ); I'd then switch off upscaling to see what that would do. What would you expect the markup to be in this case? Cheers, Chris 1 Link to comment Share on other sites More sharing options...
snck Posted June 29, 2023 Share Posted June 29, 2023 9 hours ago, nbcommunication said: What would you expect the markup to be in this case? I would expect it to contain only images with the exact dimensions I specified, like this: <picture> <source srcset="FILENAME.800x400-srcset.webp 800w, FILENAME.1600x800-srcset.webp 1600w" sizes="(max-width: 900px) 100vw, ((min-width: 901px) and (max-width: 1200px)) 67vw, ((min-width: 1201px) and (min-width: 1201px)) 50vw" type="image/webp"> <source srcset="FILENAME.800x400-srcset.jpg 800w, FILENAME.1600x800-srcset.jpg 1600w" sizes="(max-width: 900px) 100vw, ((min-width: 901px) and (max-width: 1200px)) 67vw, ((min-width: 1201px) and (min-width: 1201px)) 50vw" type="image/jpeg"> <img src="FILENAME.800x400.jpg" alt="..." class="hero-img" width="800" height="400" loading="lazy"> </picture> Instead of the 1600x800 variants I get the original image URL again. Disabling upscaling does not change it. Of course I could resize the image before rendering as in your example, but shouldn't it be possible to pass an array for the srcset and get exactly the values you specified? This is a fix of course, but feels more like a hack than a solution. Cheers, Flo Link to comment Share on other sites More sharing options...
nbcommunication Posted June 29, 2023 Author Share Posted June 29, 2023 Hi @snck, Thanks - I think I found the place where this is failing to generate the 1600x800 variation where it should. I've pushed the potential fix. Can you try it out? I would note that the example implementation I gave above (creating the variation before calling render()) is a better way to implement this as the markup is meant to be a template not a string with actual values, however if the fix I've pushed works, it should work for either implementation. Cheers, Chris 1 Link to comment Share on other sites More sharing options...
snck Posted July 3, 2023 Share Posted July 3, 2023 On 6/29/2023 at 11:04 PM, nbcommunication said: Thanks - I think I found the place where this is failing to generate the 1600x800 variation where it should. I've pushed the potential fix. Can you try it out? I would note that the example implementation I gave above (creating the variation before calling render()) is a better way to implement this as the markup is meant to be a template not a string with actual values, however if the fix I've pushed works, it should work for either implementation. Hi @nbcommunication, thanks for the quick reponse! Unfortunately the update did not solve my problem. You are right regarding the markup string, but that has nothing to do with my problem (source tags output fallback to original image instead of (upscaled) version with correct aspect ratio). I will scale the image before calling render, but if you find a solution or come up with an update, I am happy to try it again. Cheers, Flo Link to comment Share on other sites More sharing options...
gornycreative Posted July 4, 2023 Share Posted July 4, 2023 Hey there, I'm trying to track down some PHP warnings, and one comes from this module. I understand you are trying to do some error checking in the configuration in the init() function, but unless I'm totally off on this there is no page context for the init() function in modules. I get two warnings on line 68 because template is run on null and name is run on null.. $this->wire->page in the init() method is null because as far as I understand when the init() method is run there is no page actually loaded yet. As a result $isAdmin is never true and that entire module config test block never loads? The hooks are outside the block - so no problems there, but I'm guessing that clearing variations from the module config doesn't work. Link to comment Share on other sites More sharing options...
nbcommunication Posted July 4, 2023 Author Share Posted July 4, 2023 Hi @snck, Indeed, now I've tested both your and my code on an image of the width you'd specified, I can see I put the fix in the wrong place. The latest version 1.0.7 should hopefully resolve this for you. @gornycreative, How odd - I got this way of checking if it is the admin years ago from someone else's module / a mixture of forum post responses. I've never had a situation where it triggered these warnings. If I log $this->wire()->page in init() I get the Page object. However, I do agree that relying on this in init() isn't the correct implementation. In 1.0.7 I've changed this instead to (string) $this->wire()->process === 'ProcessModule' which works for me and should also hopefully resolve the warnings. Cheers, Chris Link to comment Share on other sites More sharing options...
gornycreative Posted July 4, 2023 Share Posted July 4, 2023 4 hours ago, nbcommunication said: If I log $this->wire()->page in init() I get the Page object. If I do a bd in Tracy: /** * Initialize the module * */ public function init() { $input = $this->wire()->input; // $isAdmin = $this->wire()->page->template->name === 'admin'; bd($this->wire()->page); //Should be the same bd($this->wire->page); //But Just in case I get this: Not even a NullPage object which would at least be something. I found a similar method in a thread from years ago where the limitations of init() were also mentioned. I can't recall if that's the first place I'd seen - it - perhaps in the core code itself? From wire/config.php - I think this is where I first saw hints that anything done in init() doesn't know what page exists. Quote The statuses occur in this order: * * 1. The `boot` status occurs in the ProcessWire class constructor, after PW has initialized its * class loader, loaded its config files, and initialized its hooks system. One use for this * state is to add static hooks to methods that might be executed between boot and init, which * would be missed by the time the init state is reached. * * 2. The `init` status occurs after ProcessWire has loaded all of its core API variables, except * that the $page API variable has not yet been determined. At this point, all of the autoload * modules have had their init() methods called as well. * * - If you want to target the state right before modules.init() methods are called, (rather * than after), you can use `initBefore`. * * 3. The `ready` status is similar to the init status except that the current Page is now known, * and the $page API variable is known and available. The ready file is included after autoload * modules have had their ready() methods called. But this doesn't say explicitly that you couldn't *get* the page while in the init context, just that the API var isn't instantiated yet. I'm wondering if bumping it to the ready() state would be an option? The thread I linked never really came to a satisfying conclusion - but I'd also like to know if there is a definitive best practice for how to do this. @horst @Robin S ? Link to comment Share on other sites More sharing options...
gornycreative Posted July 4, 2023 Share Posted July 4, 2023 I tried moving the error checking portion that tests for admin and processes form input to the ready() and left the hook definitions in init() and it seemed to work fine as written. Link to comment Share on other sites More sharing options...
nbcommunication Posted July 4, 2023 Author Share Posted July 4, 2023 Thanks @gornycreative, I don't use TracyDebugger (*hangs head in shame*) but I do wonder whether that is why $this->wire()->page isn't available in the init(). The test I ran was on a new install of the dev branch so it does suggest something additional altering things. Regardless, for the purposes of this module the fix I put in place to use $this->wire()->process should work. I would normally have put this logic in ready() but didn't and can't remember why, so I'd prefer to keep it where it is for now at least. Cheers, Chris 1 Link to comment Share on other sites More sharing options...
nbcommunication Posted July 26, 2023 Author Share Posted July 26, 2023 On 6/28/2023 at 11:08 AM, snck said: $img->render( [ 'picture' => true, 'srcset' => [ 'rules' => ['800x400', '1600x800'], 'options' => [ 'upscaling' => true, ], ], 'allSets' => true, 'sizes' => '(max-width: 900px) 100vw, ((min-width: 901px) and (max-width: 1200px)) 67vw, ((min-width: 1201px) and (min-width: 1201px)) 50vw', 'class' => 'hero-img', 'alt' => "...", 'markup' => "<img src='".$img->size(800, 400)->url."' alt='{alt}' class='{class}' width='".$img->size(800, 400)->width."' height='".$img->size(800, 400)->height."'>", ] ) Hi @snck, I'm just doing some testing on the module at the moment and was using this code as an example. Just wanted to let you know that 'allSets' should be set in srcset options alongside 'upscaling'. In this case, you wouldn't need to set upscaling as 'allSets' enables upscaling anyway. Cheers, Chris Link to comment Share on other sites More sharing options...
paulbrause Posted November 10, 2023 Share Posted November 10, 2023 Hello, maybe I missed something somewhere, but is it possible to append the "browser cache busting query string" when rendering? With the "normal" image this is possible via $image->URL or $image->HTTPURL, but I have not found a possibility here. Thank you very much, Christian Link to comment Share on other sites More sharing options...
nbcommunication Posted November 10, 2023 Author Share Posted November 10, 2023 Hi @paulbrause, By when rendering do you mean $pageimage->render()? I don't think it is available to this implementation. If you are using the srcset method directly you can do $pageimage->SRCSET or $pageimage->HTTPSRCSET. Cheers, Chris Link to comment Share on other sites More sharing options...
paulbrause Posted November 16, 2023 Share Posted November 16, 2023 Hi, had thought that this would somehow be possible via $pageimage->render, but via $pageimage->SRCSET is also okay. ? Thank you! Christian 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