Leaderboard
Popular Content
Showing content with the highest reputation on 11/11/2023 in all areas
-
Delayed Image Variations Delays the creation of image variations until their individual URLs are loaded. Image variations being generated one-by-one: Background Normally when you create new image variations in a template file using any of the ProcessWire image resizing methods, all the new variations that are needed on a page will be created from the original Pageimage the next time the page is loaded in a browser. If there are a lot of images on the page then this could take a while, and in some cases the page rendering might exceed your max_execution_time setting for PHP. So you might like to have image variations be generated individually when they are requested rather than all at once. That way the page will render more quickly and the risk of a timeout is all but eliminated. But there can be problems with some implementations of this approach, such as with the (in)famous TimThumb script: It's not ideal to have PHP be involved in serving every image as this is needlessly inefficient compared to serving static assets. It's not good to allow arbitrary image sizes to be generated by varying URL parameters because you might want to restrict the maximum resolution an image is available at (e.g. for copyrighted images). If images are generated from URL parameters a malicious user could potentially generate thousands of images of slightly different dimensions and fill up all your disk space. The Delayed Image Variations module avoids these problems - it creates variations when their URLs are loaded but only allows the specific dimensions you have defined in your code. It does this by saving the settings (width, height and ImageSizer options) of every new Pageimage::size() call to a queue. The module intercepts 404s and if the request is to an image variation that doesn't exist yet but is in the queue it generates the variation and returns the image data. This only happens the first time the image is requested - after that the image exists on disk and gets loaded statically without PHP. Usage In most cases usage is as simple as installing the module, and you don't need to change anything in your existing code. However, there might be some cases where you don't want the creation of a particular image variation to be delayed. For example, if you created a variation in your code and then immediately afterwards you wanted to get information about the variation such as dimensions or filesize. $resized = $page->image->width(600); echo $resized->height; echo $resized->filesize; This wouldn't work because the actual creation of the resized image hasn't happened yet and so that information won't be available. So in these cases you can set a noDelay option to true in your ImageSizer options and Delayed Image Variations will skip over that particular resizing operation. $resized = $page->image->width(600, ['noDelay' => true]); echo $resized->height; echo $resized->filesize; For advanced cases there is also a hookable method that you can return false for if you don't want a delayed variation for any particular resizing operation. Example: $wire->addHookAfter('DelayedImageVariations::allowDelayedVariation', function(HookEvent $event) { /** @var Pageimage $pageimage */ $pageimage = $event->arguments(0); // The Pageimage to be resized $width = $event->arguments(1); // The width supplied to Pageimage::size() $height = $event->arguments(2); // The height supplied to Pageimage::size() $options = $event->arguments(3); // The options supplied to Pageimage::size() // Don't delay variations if the Pageimage belongs to a page with the product template if($pageimage->page->template == 'product') $event->return = false; }); 404 handling For Delayed Image Variations to work your .htaccess file needs to be configured so that ProcessWire handles 404s. This is the default configuration so for most sites no change will be needed. # ----------------------------------------------------------------------------------------------- # 2. ErrorDocument settings: Have ProcessWire handle 404s # # For options and optimizations (O) see: # https://processwire.com/blog/posts/optimizing-404s-in-processwire/ # ----------------------------------------------------------------------------------------------- ErrorDocument 404 /index.php ProCache If you are using ProCache then make sure it is not configured to cache the 404 page or else PHP will not execute on 404s and queued image variations will not be generated. Generate queued variations Before launching a new website you might want to pre-generate all needed image variations, so no visitor will have to experience a delay while a variation is generated. To queue up the image variations needed for your site you will need to visit each page of the website one way or another. You could do this manually for a small site but for larger sites you'll probably want to use a site crawler tool such as Xenu's Link Sleuth. This may generate some image variations but it's likely that some other variations (e.g. within srcset attributes) will not be requested and so will remain queued. To generate all currently queued variations there is a button in the module config: This will search the /site/assets/files/ directory for queue files and render the variations. https://github.com/Toutouwai/DelayedImageVariations https://processwire.com/modules/delayed-image-variations/6 points
-
This week we'll take a look at a newly released module that enables you to lock page fields or properties from editing on a page-by-page basis. Originally planned as a core feature, I found it worked just as well built as a focused module, so here it is. This post serves as both an introduction to, as well as documentation for this new module— https://processwire.com/blog/posts/page-edit-lock-fields/6 points
-
@Robin S THIS IS A BLAST! I just testet it on a image-heavy site and it works perfectly. Thanks a lot!!! This definitely belongs to the core of PW in a newer version.4 points
-
I'm thrilled to announce the official release of RockPageBuilder, the game-changing tool that's set to transform your web development journey (at least ChatGPT says so ??)! With its brand new drag-and-drop interface RockPageBuilder is your secret weapon for creating outstanding ProcessWire-based websites. Get a taste of the future of web development by visiting the demo page at https://pagebuilder.baumrock.com/ and exploring the RockPageBuilder documentation at https://www.baumrock.com/en/processwire/modules/rockpagebuilder/docs/ Don't miss out on this exciting opportunity to elevate your web development game. Get ready to rock with RockPageBuilder! ??️ https://www.baumrock.com/rockpagebuilder/ Here is a quick demo video: And here is how to install it from scratch in under 5 minutes: Some showcase projects are already in the pipeline ? So be sure to subscribe to https://processwire.rocks/ or to https://www.baumrock.com/rock-monthly/ Have a great weekend!2 points
-
Fantastic(!) Such a rapid reply, and it worked! Looks like i have yet to learn much myself to be any good at php & PW APIs to deal with :). ThankYou, love the processwire community2 points
-
Hello, Error message says there's no property "field" on Page class. There are also some more mistakes. This should be better: public function ready() { $this->pages->addHookBefore('saveReady', function($event) { // Replaced saved with saveReady $page = $event->arguments(0); // Replaced [0] with (0) $summaryField = $page->summary; // Removed ->field('name') $bodyField = $page->body; // Removed ->field('name') if (empty($summaryField)) { // Removed ->value $page->summary = strip_tags(substr($bodyField, 0, 192)); // replaced $summaryField->value with $page->summary, $bodyField->value with $bodyField } }); } Note that "save" hook is executed after the page is saved, so it's too late. Documentation : Page and Pages hooks EDIT : Note that you can also do that without creating a module, just by adding the hook ($this->pages->addHookBefore...) in site/templates/admin.php2 points
-
ChatGPT found MutationObserver and helped me solve a similar issue, ie modifying ajax-loaded page content on a 3rd party SaaS platform ?1 point
-
I made some updates in v0.1.1 so that unprocessed queue files get deleted if the original Pageimage is deleted. That sounds like a simple solution. In v0.1.1 the queue file is just the variation URL with ".txt" at the end. So for a variation that will have a URL "/site/assets/files/1234/myimage.500x500.jpg" once it is created the queue file would be at "/site/assets/files/1234/myimage.500x500.jpg.txt". So in your loadFilesOnDemand() method you could check if DelayedImageVariations is installed and if so check for the existence of the queue file in addition to the variation file. @bernhard, in v0.1.2 I've changed the queue file extension to ".queue" because it will allow me to identify the queue files more efficiently for another feature I have in mind to release soon. So the section in strikethrough above will now be: In v0.1.2 the queue file is just the variation URL with ".queue" at the end. So for a variation that will have a URL "/site/assets/files/1234/myimage.500x500.jpg" once it is created the queue file would be at "/site/assets/files/1234/myimage.500x500.jpg.queue".1 point
-
@Richard Jedlička & @bernhard, just want to let you know, I did a pull request for fixing issues on non label fields and on fields "not closable". https://github.com/uiii/AdminHelperLinks/pull/6#issue-19880090381 point
-
I also experienced this issue. Following on netcarver's advice above, it turns out that my device clock is ahead by over 5 minutes. I adjusted my device time & it worked but thought a broader solution might be better. This fixed my issue. var startTime = parseInt($('#login_start').val()); // GMT/UTC // var maxSeconds = 300; // max age for login form before refreshing it (300=5min) var clientStartTime = Math.floor(new Date().getTime() / 1000); var clockDifference = clientStartTime - startTime; var maxSeconds = 300 + clockDifference; But I prefer it be done in the core, so I opened an issue in github.1 point
-
I love ChatGPT when it comes to doing weird things in JavaScript. For example, there's a 3rd party service a client of mine is using that allows you to load in custom JS and CSS to customize the appearance of their platform more to your liking. The HTML of the 3rd party service is lacking in some CSS classes on some elements, so I can't hook into those elements to style them more precisely. To further complicate things, those elements only appear after an AJAX request is done. So I needed to add extra classes on particular elements in the HTML every time an AJAX request was made. I don't keep up with JS, but after giving it a nice prompt, BOOM, there's the answer with MutationObserver, XMLHttpRequest and addEventListener. This literally saved me a day, if not more, and tons of headache.1 point
-
Here's a function that would return all the children in a month. Replace the last param ($field) with the name of the date field you want it to look at, otherwise it defaults to the 'modified' field, which probably isn't what you want (but was what I used to test the function). <?php /** * Return all of the page's children where $field falls in $month and $year. * * @param Page $page The page that has the children we are finding. * @param int $month Month you want to match. * @param int $year Year you want to match. * @param string Name of the date field to check. * @return PageArray All the matching children. * */ function childrenInMonth($page, $month, $year, $field = 'modified') { $startTime = strtotime("$month/1/$year"); $endTime = strtotime("next month", $startTime); return $page->children("$field>=$startTime, $field<$endTime, sort=$field"); } Below is an example of how you might use this function in your template. This code shows examples for both URL segments and GET vars. If you wanted to use URL segments, you would need to go in to the Admin CP, click on Setup > Templates > Your Template > Advanced > URL Segments > Set it to an asterisk "*". That tells it to allow any URL segments to pages using that template. And here is code that first checks for a URL segment, then GET vars, and defaults to current month/year if none is provided. <?php if($input->urlSegment1 && preg_match('/^(\d{4})-(\d{1,2})$/', $input->urlSegment1, $matches)) { // A URL segment matched in the format of year-month, i.e. /news/2010-12 $month = $matches[2]; $year = $matches[1]; } else if($input->get->month && $input->get->year) { // GET vars were provided with the year and month $month = (int) $input->get->month; $year = (int) $input->get->year; } else { // No year/month provided, so display items from current month $month = date('m'); $year = date('Y'); } // display a headline with selected month/year echo "<h2>" . date('F Y', strtotime("$year-$month")) . "</h2>"; // find the matching pages $children = childrenInMonth($page, $month, $year); // output a list of the matching pages echo "<ul>"; foreach($children as $child) { echo "<li><a href='{$child->url}'>{$child->title}</a></li>"; } echo "</ul>";1 point