Jump to content


  • Posts

  • Joined

  • Last visited

  • Days Won


nbcommunication last won the day on April 19

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 @Kiwi Chris, The admin needs the local copy, from what I can see it is mainly for the file size displayed beside the filename in the admin. I did look at hooking InputfieldFile::render() to replace this but I eventually decided that it made sense to keep the original file in place when uploaded, and if it didn't exist to download from the R2 copy. I was thinking here of worst case scenario where Cloudflare Images has a major service outage. In a multi-server environment I could perhaps query each server to see which has the most files and switch off the rest of the servers, and switch off the CF integration on the chosen server. That way a site could continue to function. A very unlikely situation but I'd like that option. What it doesn't do (or shouldn't do, haven't fully tested it yet) is create the size variation image locally. Calls to Pageimage::size() should just create a variant in Cloudflare Images if it doesn't already exist. Unfortunately there is a limit of 100 variants (which can be applied to every image upload, it isn't a limit of 100 actual images), which while sufficient for a single development, means that the service cannot be used for multiple sites, unless they are creating the same variants. I did expect to keep this and the other modules I posted at the start of the week internal as they are somewhat specific to our needs, but after consideration I figured it would make sense for them to get other eyes on them and some differing perspectives - if you do go down the route of Cloudflare Images with your own integration please use this work as reference and please do share any solution you reach! Cheers, Chris
  2. It didn't take long for the changes to the Images implementation - it turns out that image options are available for named variants, just not documented. The module now uses named variants instead of flexible variants. More notes etc to be added to the README in the next month or so.
  3. 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
  4. Extends Pagefile to use Cloudflare Images, Stream and R2 storage to serve files. https://github.com/nbcommunication/CloudflareAssets The main purpose of this module is to allow ProcessWire to be used in an auto-scaling multi-instance environment. By serving file assets from Cloudflare, it is not necessary to have all file assets copied to all instances and we also get the benefits of serving assets from a CDN. How it works When a Pagefile is added in the admin or via the API, it is uploaded to Cloudflare's R2 storage service. Additionally, if the file is an image, it is uploaded to Cloudflare Images, and if the file is a video it is uploaded to Cloudflare Stream. When a URL for the Pagefile is requested e.g. $pagefile->url(), the appropriate Cloudflare URL is returned. As ProcessWire's admin still requires the file to be available locally, in a multi-instance setup if a file is not available it is downloaded from the 'master' copy in R2. This module is not yet being used in production. There may be changes to how Images work in the coming months as features are still being rolled out to this Cloudflare service. Cheers, Chris
  5. Synchronises ProCache clearing across a multi-instance environment. https://github.com/nbcommunication/ProCacheSync The main purpose of this module is to allow ProCache to be used in an auto-scaling multi-instance environment. How it works When a page is saved and cache clearing is triggered, the page id(s) associated with that clear are saved to the database. ProCacheSync runs a check every minute via LazyCron to look for records in the database since ProCache was last cleared. If it finds any it processes them as ProCache would. Any records it finds will have been generated by a clear on another server instance, thus enabling multiple instances of ProCache to stay approximately synchronous. This module is not yet being used in production. Cheers, Chris
  6. 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
  7. 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
  8. 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
  9. 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
  10. 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 🙂
  11. Hi @DV-JF, Thanks but no need, I'm always glad to hear that the module is getting used! Cheers, Chris
  12. 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
  13. 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
  14. Hi @DV-JF, Is there anything in Setup -> Logs? Cheers, Chris
  15. 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
  • Create New...