snck
Members-
Posts
94 -
Joined
-
Last visited
Everything posted by snck
-
@ryan Today I made another observation. I used the rename() method on the Pagefiles object and got a fatal error: $this->wire->addHookAfter("Pages::saved(template^=application_entry)", function(HookEvent $event) { $page = $event->arguments(0); // get all fields of fieldtype file $fileFields = $page->fields->find('type=FieldtypeFile'); $page->of(false); // loop through all file fields foreach($fileFields as $field){ $fieldname = $field->name; $field = $page->get($field->name); $index = 1; foreach($field as $item){ $newFilename = $fieldname; // if there are multiple files, add index to filename if(count($field) > 1){ $newFilename .= "-".$index; $index++; } $newFilename .= '.'.$item->ext; bd($item->basename()." -> ".$newFilename); // only rename if filename is not already set if($item->basename() != $newFilename){ // $item->rename($newFilename); $field->rename($item, $newFilename); } } } $page->save(); }); 1024 MiB exhausted?
-
I am using FormBuilder to collect data and save it to pages. The forms (and the page templates used) use file fields to collect PDF files. The uploaded files should automatically be renamed to match the name of the fields. This should happen every time a page is saved. The first time after the form is saved to the page, but also on every other page save, because editors could have added or exchanged some of the files and then they should be renamed again. I tried to solve this in different ways, but nothing really worked as expected. What I tried: $this->wire->addHookBefore("Pages::saveReady(template^=application_entry)", function(HookEvent $event) { $page = $event->arguments(0); // get all fields of fieldtype file $fileFields = $page->fields->find('type=FieldtypeFile'); // loop through all file fields foreach($fileFields as $field){ $fieldname = $field->name; $field = $page->get($field->name); $index = 1; foreach($field as $item){ $newFilename = $fieldname; // if there are multiple files, add index to filename if(count($field) > 1){ $newFilename .= "-".$index; $index++; } $newFilename .= '.'.$item->ext; // bd($item->basename()." -> ".$newFilename); // only rename if filename is not already set if($item->basename() != $newFilename){ $item->rename($newFilename); } } } $event->arguments(0, $page); }); When I save an existing page, the files are renamed, but I get the following error message and the filename change is not reflected in the database: If the page has not existed before save (got created by FormBuilder) I get a message that it was created, but it does not get created and FormBuilder shows a Not yet created in the entries list. Another approach was this: $this->wire->addHookAfter("Pages::saved(template^=application_entry)", function(HookEvent $event) { $page = $event->arguments(0); // get all fields of fieldtype file $fileFields = $page->fields->find('type=FieldtypeFile'); $page->of(false); // loop through all file fields foreach($fileFields as $field){ $fieldname = $field->name; $field = $page->get($field->name); $index = 1; foreach($field as $item){ $newFilename = $fieldname; // if there are multiple files, add index to filename if(count($field) > 1){ $newFilename .= "-".$index; $index++; } $newFilename .= '.'.$item->ext; bd($item->basename()." -> ".$newFilename); // only rename if filename is not already set if($item->basename() != $newFilename){ $item->rename($newFilename); $page->save(); } } } }); This also renames the file on save, but the filename in the field is still the old name. I am using pagefileSecure on this template (if that matters). Any help his highly appreciated! Thanks in advance, Flo
-
Hey @Juergen, today I ran into a really strange issue and it took me a while to track it down. I use FormBuilder and automatically save entries to PW pages. I had the issue that although I selected to save to published pages (in FormBuilder config for the form) my pages always had the unpublished status. I wanted to blame FormBuilder first, but then I noticed that there was a hook in JKPublishPages on page save: /** * Set page status to unpublished or remove unpublished status depending on if date range is out of date or not * This runs on manual save * @param HookEvent $event * @return void */ protected function setPageStatusManually(HookEvent $event): void { $page = $event->arguments(0); $from = true; if ($page->jk_publish_from) { $from = $page->jk_publish_from < time(); } else { $page->jk_publish_from = time(); } $to = true; if ($page->jk_publish_until) { $to = ($page->jk_publish_until > time()); } if (!$from || !$to) { $page->addStatus(Page::statusUnpublished); } } Shouldn't this contain a check so it only applies to the templates selected in JKPublicPages' module settings? In my case it sets pages that have no jk_publish_from and jk_publish_to fields to unpublished. When I comment out $page->addStatus(Page::statusUnpublished); or deactivate your module everything works as expected. Could you please check that and provide a fix? I guess this causes issues for others as well when creating pages from the API. Cheers, Flo
-
I had a problem with PHP 8.1.8 an saving pages containing the field. I got this error: I changed lines 193 and 194 to make sure all values that get rounded are floats: if( ((string) round(floatval($lat), $precision)) != ((string) round(floatval($this->defaultLat), $precision)) || ((string) round(floatval($lng), $precision)) != ((string) round(floatval($this->defaultLng), $precision))) { Maybe this could be included in a future version? Cheers, Flo
-
module PrivacyWire - Cookie Management & async external asset loading
snck replied to joshua's topic in Modules/Plugins
I stumbled upon a thing that might be a bug. I want to embed this podcast player: <script class="podigee-podcast-player" data-src="https://player.podigee-cdn.net/podcast-player/javascripts/podigee-podcast-player.js" data-configuration="..."></script> I am using the following code: <script type="text/plain" data-type="text/javascript" class="podigee-podcast-player" data-ask-consent="1" data-category="external_media" data-src="https://player.podigee-cdn.net/podcast-player/javascripts/podigee-podcast-player.js" data-configuration="..."></script> The placeholder is appearing just fine, but when the user accepted the cookie, I only get this: <script data-configuration="..." type="text/javascript" src="https://player.podigee-cdn.net/podcast-player/javascripts/podigee-podcast-player.js" async=""></script> The class attribute (class="podigee-podcast-player") is getting removed and therefore the player will not load. I guess that this is not the intended behavior? Cheers, Flo -
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
-
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
-
@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?
-
Hi @nbcommunication, thanks for the quick reaction! The update fixed it for me. ? Cheers, Flo
-
Hey @nbcommunication, I have a strange problem here. I am using the following code: $img->render([ 'picture' => true, 'srcset' => [ 'rules' => ['800x267', '1600x534'], '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' => $img_class, 'alt' => $alt, 'markup' => "<img src='".$img->size($img_tag_width, $img_tag_height)->url."' alt='{alt}' class='{class}' width='".$img->size($img_tag_width, $img_tag_height)->width."' height='".$img->size($img_tag_width, $img_tag_height)->height."'>", ]); My image has a width of 1600px, but a different aspect ratio (original dimensions: 1600 x 1093). I am expecting to get two variations rendered ('800x267', '1600x534'), but instead of a scaled/cropped 1600px wide version, I get the original image, which is bad, because it has the wrong aspect ratio. How can I force PageimageSource to generate the variation with the correct dimensions? Thank you in advance!
-
Thanks, @teppo! ? I am facing a different problem now. I have a site in debug mode and was not able to upload images realiably since installing SearchEngine. I found out that the JSON response of the server for the image upload returned a PHP error related to the Indexer: I am using a RepeaterMatrix field on the page (and Repeaters nested in RepeaterMatrix fields on other pages). Do you have a solution for this problem? Obviously disabling debug mode is a temporary fix, but not ideal.
-
I am using RockMigrations for a while now (and am honestly in love with it!) and just recently ran into a problem that I had not encountered before. I am using the deployment features and a setup that automatically deploys the two (dev and main) branches in my Github repo to different locations. This works perfectly fine most of the time, however last time PHP ran out of memory and I did not notice it, because the job was marked as successful in Github actions. Running out of memory led to the current symlink not getting generated and the website being not accessible (without me noticing it). @bernhard and I already had a chat about it, but we were wondering whether you guys had ideas or suggestions on how to deal with errors and warnings during the deployment process and appreciate your input.
-
From my understanding is_nan(null) === false (in prior PHP versions). To fix lines 247 and 248 something like the following should do the trick: if($c2 !== null && is_nan($c2)) $e3 = $e4 = 64; else if($c3 !== null && is_nan($c3)) $e4 = 64; At least for me this stops the deprecation warning from appearing and keeps the functionality.
-
Thanks for your reply! You're right that the number of matches is not necessarily an indicator for relevancy. As I stumbled over the quoted question I was just curious whether there was a selector or option that would allow me to quickly try it out because I have a project that could benefit from it. SearchEngine is a great module nonetheless. ?
-
Hi @teppo, as I could not find an answer to this old question: Is there a way to sort the results by number of matches / occurences? That would be awesome!
-
@bernhard I was a little confused whether RepeaterMatrix fields are (still) supported or not. I found this discussion concerning RockMigrations1 and was somehow expecting that the support for RepeaterMatrix fields was also ported to RockMigrations(2). Are RepeaterMatrix fields still supported and if not, do you have any plans to change that? Cheers, Flo
-
@bernhard Thanks! ? I was looking for a nice way to compile some SCSS (Bootstrap in my case) the other day and as Sassify has not been updated for almost 4 years I had a look into your Scss module. It might not have been your intention, but as this a viable wrapper for scssphp I could use it for my case as well. Maybe this can be a starting point for somebody else looking for a way to compile something else than the PW core: <?php $compiler = $modules->get('Scss')->compiler; $input_scss = $this->wire->config->paths->templates."scss/custom.scss"; $bootstrap_scss_path = $this->wire->config->paths->templates."bootstrap/scss"; $output_css = $this->wire->config->paths->templates."css/bootstrap_custom.css"; $output_map = $this->wire->config->paths->templates."css/bootstrap_custom.map"; $compiler->setSourceMap($compiler::SOURCE_MAP_FILE); $compiler->setSourceMapOptions([ // relative or full url to the above .map file 'sourceMapURL' => $output_map, // (optional) relative or full url to the .css file 'sourceMapFilename' => $output_css, // partial path (server root) removed (normalized) to create a relative url 'sourceMapBasepath' => $this->wire->config->paths->root, // (optional) prepended to 'source' field entries for relocating source files 'sourceRoot' => '/', ]); $compiler->addImportPath($bootstrap_scss_path); $compiler->setOutputStyle("compressed"); $result = $compiler->compileString('@import "'.$input_scss.'";', $this->wire->config->paths->templates."scss"); file_put_contents($output_map, $result->getSourceMap()); file_put_contents($output_css, $result->getCss()); ?>
-
RockFrontend 🔥🚀 The Powerful Toolbox for ProcessWire Frontend Development
snck replied to bernhard's topic in RockFrontend
Hey @bernhard, as you have recently released the Scss module, are there any plans to add SCSS compilation capabilities (if the module is installed) to RockFrontend as well? I'd love to be able to recompile Bootstrap automatically whenever files have changed and as this logic is already present in RockFrontend, this looks like a perfect addition to me. If you consider it, it would be great to be able to pass options to the compiler. Cheers, Flo -
@nbcommunication Thank you for clarification and the great example. I will definitely keep this in mind! ?
-
@bernhard Imho modifiers like 2x should not be necessary at all. It took me quite some time and testing to wrap my head around responsive images and my experiments with the current browsers showed that whenever my sizes attribute was accurate, the browser chose the closest image resolution from the sourceset taking pixel density of the screen into account automatically. This is a (rather complex) example for my usage of PageimageSource on a page with a masonry style layout that can have from 1 to 5 columns and the sizes also take padding etc. into account (which might be overkill): $img_markup = $img->render([ '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, 'markup' => "<img src='{$img->width(480)->url}' alt='{alt}' class='{class}' width='".$img->width(480)->width."' height='".$img->width(480)->height."'>" ]); Output: <picture> <source srcset="/site/assets/files/1200/1_klimanagepasster_wohnunsgbau.360x0-srcset.webp 360w, /site/assets/files/1200/1_klimanagepasster_wohnunsgbau.480x0-srcset.webp 480w, /site/assets/files/1200/1_klimanagepasster_wohnunsgbau.640x0-srcset.webp 640w, /site/assets/files/1200/1_klimanagepasster_wohnunsgbau.800x0-srcset.webp 800w" 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))" type="image/webp"> <source srcset="/site/assets/files/1200/1_klimanagepasster_wohnunsgbau.360x0-srcset.jpg 360w, /site/assets/files/1200/1_klimanagepasster_wohnunsgbau.480x0-srcset.jpg 480w, /site/assets/files/1200/1_klimanagepasster_wohnunsgbau.640x0-srcset.jpg 640w, /site/assets/files/1200/1_klimanagepasster_wohnunsgbau.800x0-srcset.jpg 800w" 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))" type="image/jpeg"> <img src="/site/assets/files/1200/1_klimanagepasster_wohnunsgbau.480x0.jpg" alt="Klimanagepasster Wohnunsgbau" class="teaser-img proportional" width="480" height="282" loading="lazy"> </picture> @nbcommunication Great module, I like it a lot! Nevertheless my example also shows a little incovenience I experienced when using PageimageSource: I need to output width and height attributes for my img tag and using the markup option (as shown above) was the only way to accomplish this. Using the height and width options of the render method rendered the srcset useless (all the same sizes). Maybe you could implement an option that outputs the size of the first entry from the srcset as width and height attributes of the img? Especially when using lazyloading the width and height attributes serve as proportional placeholders and prevent layout shifts. Cheers, Flo
-
Great module, @Sebi! As it is out there for almost 2 years now, maybe someone found an elegant solution for caching the generated output (and rebuilding that cache if a page or child page is updated)? I have seen @toni´s approach and could build something on top of that for my specific use case, but I guess there are a lot of people having similar needs and would love to see something that is more ready to use. I am not experienced with ProCache, but I think being able to use ProCache to cache API output would not only be the most elegant way, but also one of the fastest possible.
-
Max execution time exceeded in Pageimage.php for specific pages
snck replied to snck's topic in General Support
Hey @adrian, you are right. I was thinking of the viewBox as a set of coordinates in x/y dimension that are defining the corners of the viewbox relative to the origin of the coordinate system (this is why i called them max_x and max_y), which is obviously wrong. It should look like this: /** * Gets the image info/size of an SVG * * Returned width and height values may be integers OR percentage strings. * * #pw-internal * * @param string $filename Optional filename to check * @return array of width and height * */ protected function getImageInfoSVG($filename = '') { $width = 0; $height = 0; if(!$filename) $filename = $this->filename; $xml = @file_get_contents($filename); if($xml) { $a = @simplexml_load_string($xml)->attributes(); if((int) $a->width > 0) $width = (int) $a->width; if((int) $a->height > 0) $height = (int) $a->height; // start viewbox fix if(!$width || !$height){ if($a->viewBox != ""){ // get rid of commas: replace them with spaces $a->viewBox = str_replace(",", " ", $a->viewBox); // get rid of (now possible) double spaces: replace them with a single space $a->viewBox = str_replace(" ", " ", $a->viewBox); // get single values $viewbox = explode(" ", $a->viewBox); if(count($viewbox) === 4){ // we need 4 values, even though we are just using 2 $width = (float) $viewbox[2]; $height = (float) $viewbox[3]; } } } // end viewbox fix } if((!$width || !$height) && (extension_loaded('imagick') || class_exists('\IMagick'))) { try { $imagick = new \Imagick(); $imagick->readImage($filename); $width = $imagick->getImageWidth(); $height = $imagick->getImageHeight(); } catch(\Exception $e) { // fallback to 100% } } if($width < 1) $width = '100%'; if($height < 1) $height = '100%'; return array( 'width' => $width, 'height' => $height ); } @ryan, maybe something like this could be a useful addition to the core?- 13 replies
-
- 1
-
- pageimage.php
- imagick
-
(and 1 more)
Tagged with:
-
Max execution time exceeded in Pageimage.php for specific pages
snck replied to snck's topic in General Support
@adrian Again had problems with this and got back to your idea. Thank you so much! This quick fix might be not the most beautiful/efficient way, but worked fine for me (and might also for someone else): /** * Gets the image info/size of an SVG * * Returned width and height values may be integers OR percentage strings. * * #pw-internal * * @param string $filename Optional filename to check * @return array of width and height * */ protected function getImageInfoSVG($filename = '') { $width = 0; $height = 0; if(!$filename) $filename = $this->filename; $xml = @file_get_contents($filename); if($xml) { $a = @simplexml_load_string($xml)->attributes(); if((int) $a->width > 0) $width = (int) $a->width; if((int) $a->height > 0) $height = (int) $a->height; // start viewbox fix if(!$width || !$height){ if($a->viewBox != ""){ // get rid of commas: replace them with spaces $a->viewBox = str_replace(",", " ", $a->viewBox); // get rid of (now possible) double spaces: replace them with a single space $a->viewBox = str_replace(" ", " ", $a->viewBox); // get single values $viewbox = explode(" ", $a->viewBox); if(count($viewbox) === 4){ // we need 4 values $min_x = (float) $viewbox[0]; $min_y = (float) $viewbox[1]; $max_x = (float) $viewbox[2]; $max_y = (float) $viewbox[3]; $width = $max_x - $min_x; $height = $max_y - $min_y; } } } // end viewbox fix } if((!$width || !$height) && (extension_loaded('imagick') || class_exists('\IMagick'))) { try { $imagick = new \Imagick(); $imagick->readImage($filename); $width = $imagick->getImageWidth(); $height = $imagick->getImageHeight(); } catch(\Exception $e) { // fallback to 100% } } if($width < 1) $width = '100%'; if($height < 1) $height = '100%'; return array( 'width' => $width, 'height' => $height ); }- 13 replies
-
- 1
-
- pageimage.php
- imagick
-
(and 1 more)
Tagged with:
-
module PrivacyWire - Cookie Management & async external asset loading
snck replied to joshua's topic in Modules/Plugins
Thanks a lot for this wonderful module! It works like a charm, except for one little problem: When I use the "Accept all" button I have to reload the website for the changes to take effect. Selecting specific categories and clicking the "Save preferences" button has immediate effect. Is this an indented behaviour or am I missing something here?