-
Posts
286 -
Joined
-
Last visited
-
Days Won
7
Everything posted by nbcommunication
-
Note to anyone using potentially using this module: A page-edit-redirects permission has been added to the core - https://github.com/processwire/processwire/commit/dafceffc6f5d2d10c395faa1586ef0993633e6de - and once this hits the master branch I intend to rework this module so that it provided a list of redirects in the system. As the permission can be added to any user role, management of those redirects will happen in the page editor instead of the 'cloned' redirects editor this module currently provides. Cheers, Chris
-
Hi, I've been trying to get the active status of languages to update based on other info on the page, in this case I only want a language to be active if there is a file tagged with its name: <?php // admin.php $pages->addHook('saveReady', function(HookEvent $event) { $page = $event->arguments('page'); foreach($event->wire()->languages->findNonDefault() as $language) { $key = "status$language->id"; if($page->id) { $page->set($key, $page->resource->findTag($language->name)->count ? 1 : 0); } else { $page->setQuietly($key, 0); } } }); I've tried all sorts of approaches but nothing works. It seems as if there is a Page cache issue here. Tried $pages->uncache() but that didn't seem to work either... Anyway, I 'solved' it like so: <?php // admin.php $wire->addHook('InputfieldPageName::render', function(HookEvent $event) { $page = $event->object->editPage; if($page && $page->id) { foreach($event->wire()->languages->findNonDefault() as $language) { $page->setQuietly("status$language->id", $page->resource->findTag($language->name)->count ? 1 : 0); } } }); It does require the user to then save the page, but it is definitely better than having all the languages active when I only need some. Hope this is useful... Cheers, Chris
-
Hi @mel47, This module isn't built to handle art direction I'm afraid, it is to provide a srcset property to a single Pageimage. Art direction will likely require more than one Pageimage (as your example suggests) so this would need to be handled with your own code. However, the module should still be useful for your example; use ->srcset instead of ->url in the <source srcset> attribute. Cheers, Chris
-
Almost every time. I think we're just a bit spoiled with the PW API, but it is always a bit of a shock to work with API data that needs to be wrestled into shape before we can do what we want to do. I'm not sure I could even wrestle it into shape if it wasn't for PW.... On the plus side, at least that API is documented and returning JSON ?
-
Hi @DV-JF, Thanks but no need, I'm always glad to hear that the module is getting used! Cheers, Chris
-
Hi @DV-JF, It happens because Instagram/Facebook invalidates the (authorised) access token if the user changes their password. I guess from the error message (Facebook has changed the session for security reasons) other security issues can lead to it happening too. It isn't in the scope of the module to notify admins, but it should be pretty easy to implement. Try something like: <?php $instagram = $modules->get('InstagramBasicDisplayApi'); $items = $instagram->getMedia(); if(!($items instanceof WireArray) || !$items->count) { $cache->getFor($instagram, 'errorNotifyAdmin', 'daily', function() use ($config, $instagram, $log, $mail) { return $mail->new() ->to($config->adminEmail) ->subject("$instagram error") ->bodyHTML('<p>' . implode('<br>', $log->getLines( $instagram->className(['lowercase' => true]), ['limit' => 10] )) . '</p>') ->send(); }); } This would send the admin an email every day if no media is being returned, with the email being the last 10 log messages. Cheers, Chris
-
Hi @DV-JF, Ah yes, this is a total pain when this happens. We've had this happen on sites where we don't have much contact with the client, as since we need them to re-authorise, the feed is just lying empty. Anyway, going through the authorisation process again should fix this. Cheers, Chris
-
Hi @DV-JF, Is there anything in Setup -> Logs? Cheers, Chris
-
Hi @Stefanowitsch Yes, and the same focus point would be used. I think if you are looking for a different focus point / crop you might be better off trying to output the <picture> html manually. I see from the source code that the 2nd argument (options) is passed to the size() call. Might be worth trying adding 'cropping' to this - https://processwire.com/api/ref/pageimage/size/ - and see if it works! As for updating the image when the viewport shrinks... I've no idea I'm afraid. If the UIkit implementation can do this - that is it doesn't use the largest image loaded but always the one specified by sizes - you'd need to ask their devs if it isn't working. Actually come to think of it, why not render two images and use uk-hidden@s and uk-visible@s classes to toggle between them? Cheers, Chris
-
Hi @Stefanowitsch, Try: <?php $img = $image->render([ 'srcset' => [ 'rules' => '320x569, 640x1138, 768x1365, 1024, 1366, 1600, 1920', // first three rules here are for portrait images 'options' => [ 'upscaling' => true, 'hidpi' => true, ], ], 'sizes' => '(orientation: portrait) and (max-width: 640px) 50vw', ]); This is adapted from an example in the README which itself was adapted from an implementation in PageimageSrcset - I can't remember exactly how this works but I have used it in the past for portrait images on mobile. Cheers, Chris
-
Hi @Stefanowitsch, A different variation of the Pageimage, or a totally different Pageimage? Cheers, Chris
-
Hi @Stefanowitsch, I've used this UIkit implementation in a few recent projects, I wrote up how I did it here: Hope that helps! Cheers, Chris
-
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
-
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
-
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
-
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
-
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
-
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.
-
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
-
Hi @t0b1, Thanks, I must've missed this when writing up the README. That's it added now. Cheers, Chris
-
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
-
Weekly update – 24 June 2022: Simple list cache
nbcommunication replied to ryan's topic in News & Announcements
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 -
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
-
Me too ?
-
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