Jump to content

nbcommunication

Members
  • Posts

    319
  • Joined

  • Last visited

  • Days Won

    9

Everything posted by nbcommunication

  1. Purge the StackPath CDN cache when ProCache clears. https://github.com/nbcommunication/ProCacheStackPath If you use StackPath's CDN to deliver your website, you need a way to clear its cache when ProCache clears. This module connects with your StackPath stack via the StackPath API and when ProCache clears it requests StackPath clear the cache, attempting to respect the specific rules (Parents, Family, Children etc) set up in ProCache. This module is being using in production but only for a couple of sites that just clear the whole cache when a page is saved. The implementation of the Parents / Family / Children rules haven't been fully tested, and it isn't clear from StackPath's documentation whether their 'recursive' option only works from the root URL or from internal pages too. Hopefully it does and I'll hopefully get it tested soon. Cheers, Chris
  2. 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
  3. 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
  4. 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
  5. 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 ?
  6. Hi @DV-JF, Thanks but no need, I'm always glad to hear that the module is getting used! Cheers, Chris
  7. 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
  8. 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
  9. Hi @DV-JF, Is there anything in Setup -> Logs? Cheers, Chris
  10. 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
  11. 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
  12. Hi @Stefanowitsch, A different variation of the Pageimage, or a totally different Pageimage? Cheers, Chris
  13. 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
  14. 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
  15. 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
  16. 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
  17. 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
  18. 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
  19. 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.
  20. 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
  21. Hi @t0b1, Thanks, I must've missed this when writing up the README. That's it added now. Cheers, Chris
  22. 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
  23. 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
  24. 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
×
×
  • Create New...