Jump to content

Leaderboard

Popular Content

Showing content with the highest reputation on 04/29/2022 in all areas

  1. This week's commits for ProcessWire 3.0.199 focus primarily in wrapping up several remaining reported issues in preparation for our master/main release version. So you can think of 3.0.199 as very close to a release candidate for the next master/main version. A few of the issues resolved this week were ones that had been around a long time, due to being difficult to reproduce, or issues that had been held off for awhile because they were going to take additional time to resolve. (See commit log for details). Having closed out a few of those older issues this week, I'm feeling good about where the dev branch is right now and think we're just about there. If you have a chance to test out the current dev branch (3.0.199), please let us know if you run into any issues. At least one person has asked about why we're not bumping the version to 3.1 (previously, or now). The reason is that all 200 versions of 3.x should be compatible with each other, enabling one to upgrade (or potentially downgrade) between the 3.x versions, without any drama. That's a good thing I think, and so I'm kind of proud that we are approaching version 3.0.200, which will hopefully be our next master. I'm sure we'll have a 3.1 at some point in time, but I'd like to keep on the 3.0.x track so long as upgrades remain drama free. Thanks, and have a great weekend!
    9 points
  2. Great news! Having a recent master version is always a good thing. And maybe it is a good time to think about the roadmap for the future? Maybe even about those breaking changes, that could make 3.1 от even 4.0 a necessity? Something that revolutionize PW dev once again. I remember when 3.0 was planning. I didn't even understand what namespaces are back then)) But now I can't imagine staying at 2.x and love that that move was made on time. What is the next step?
    4 points
  3. @theoretic Sounds like a fun project. If I understand correctly, you are doing a select to read the value, then incrementing the value in PHP, then writing the value. With concurrent requests doing that, there's always a gap between the read and the write, so you should expect that some of the requests are naturally going to collide, unless you use a different strategy. What you probably need instead is a single update query that does a "col=col+1" instead. Otherwise you'll have multiple requests reading a value (like the number "3"), incrementing it, then writing the same number "4" to the DB. So the final number would always be less than the number of requests sent. The reason being that some other request may have incremented the value in between the time another request read and then wrote the value, so they'd always be overwriting each other, writing the same "4" to the DB. If you need separate read/write queries, you'd need to obtain both a read and write lock to the table row you intend to update, before you even read the value. And you'd need to release the lock after you write the value. You'd also have to account for the cases where you cannot obtain a lock (due to being locked by another request), by having a retry mechanism. Without a retry mechanism, you'll also end up with some unaccounted for requests. A good example of the pattern you are trying to achieve is implemented in the SessionHandlerDB module. It has to obtain a read/write row lock and read the session values. Then at the end of the request, it has to write the session values, then release the row lock. That way concurrent requests in the same session can't overwrite each other's data. But it also means that concurrent requests are queued and have to wait in line for their turn to control the data. The same would be true in your test case. Lastly, pay attention to the http response code on the concurrent requests. Requests can be refused, especially if concurrent from the same session or IP. They can be refused by Apache or PW. So a request cannot count towards a total unless it returns a "200 OK" response code (this would be true for any concurrent testing of web requests whether w/PW or elsewhere).
    4 points
  4. If you are working with CSV, don't forget about the new $files->getCSV() ? while($row = $files->getCSV('/path/to/foods.csv')) { echo "Food: $row[Food] "; echo "Type: $row[Type] "; echo "Color: $row[Color] "; } https://processwire.com/talk/topic/26929-pw-30197-– core-updates/
    4 points
  5. Yes, it will break. I gave the link to the blog post introducing "owner" selectors in the code, but here it is again: https://processwire.com/blog/posts/processwire-3.0.95-core-updates/ So this selector... template=colour, select_colour.owner.template=animal, select_colour.owner.id!=$page->id ...is saying... Match pages where: the page template is "colour" and the page is selected in a field named "select_colour" and the page containing the select_colour field is using the template "animal" and the page containing the select_colour field is not the page represented by the $page variable (i.e. the page that is currently open in Page Edit)
    3 points
  6. Triasima, a portfolio management company, asked the agency Contractuelle to revamp its web image. Spiria was the contractor for the site integration. While seemingly straightforward, there were a few challenges ahead, including managing three distinct regions that shared a lot of content: Canada, the United States and the Rest of the World. Two of these regions were assigned a sub-domain (us. and world.). We did not need a multi-site module. Within each region, the visitor has to choose a type of investment profile. One of these profiles could only be selected by the Canadian region. Each profile shares some content but is identified by colour. In short, a small puzzle solved with very little code and CSS. We made extensive use of field repeaters to create a nice administration interface. We have designed "presentation scenarios" that allow the administrator to set up pages as they wish. Only the header and footer are fixed. https://triasima.com
    2 points
  7. This week on the dev branch we've got a good mix of updates and issue resolutions, though not quite yet enough yet to bump the version number just yet. But here's a few highlights: There's a PR from Adrian committed which adds configurable columns for Selector fields. System update 20 was added which fixes the "created user" for several system pages. WireHttp was updated to support sending cookies in GET/POST requests powered by CURL. Lister was updated to recognize non-sortable fields, preventing unnecessary error messages. There were also 3 issue resolutions this week. We are getting down to the smaller stuff in terms of updates, which means it's about time to get that next master version out. I know I've been talking about it for awhile, but think we'll likely have one more dev branch version (3.0.199) and then it's looking like our 200th 3.x version will tentatively be the next master version (3.0.200). Thanks for reading, Happy Earth Day, and have a great weekend!
    1 point
  8. I know this may not be true to keeping PW lean, but having HTMX integration built in for live updates to content blocks would seriously kick butt. Sort of comparable to Livewire in Laravel. That would be incredible for 4.0.
    1 point
  9. What about the "X-Requested-With: XMLHttpRequest" header? The $config->ajax call requires that to be sent.
    1 point
  10. Well, @fruid stated, that he already used halt and it did not work. I experienced the same (but I am also using Smarty Template Engine), thats why I use die() instead.
    1 point
  11. Worth noting: https://processwire.com/blog/posts/processwire-2.6.8-brings-new-version-of-reno-admin-theme-and-more/#new-this-gt-halt-method-for-use-in-template-files quote: "Now you can call return $this->halt(); from within any template file, and it will prevent further output from that template file (and anything that comes after it, like an appendTemplateFile). This enables output to stop, but PW's normal execution and shutdown process to proceed normally. Please note that return $this->halt(); must be called from directly within the template file, outside of any function or class scope."
    1 point
  12. Hi friends! Many thanks for the brilliant Processwire! I have an interesting question concerning concurrent requests. I'm working on a PW-driven API which should pass some tests required by my client, including a so-called concurrent request test. The test harness generates a certain number of unique http requests and "fires" them in almost no time (they're received by webserver with time difference of the order of milliseconds). However far from real life use cases, this test is absolutely required by my client. Experiencing such a high (however short) load, PW reveals some weaknesses mainly concerning database interaction. Almost all concurrent requests should update a PW-driven numeric data field (in fact a database table). Concurrent requests try to increment/decrement its value, and after that a final check of the field value is performed. In most cases the final check fails. In-depth study shows that PW may receive new requests before the current request is processed, and this may lead to wrong final value. I tried some possible solutions: Wrapping field-changing operations in a database transaction. No success. Using mysql table lock. In my case this also didn't give a versatile result. Writing a lock mechanism denying any operation with data field until the previous request(s) are ended. Not versatile enough again. Organizing request queue. Maybe the best possible solution, but didn't try it yet. So what are your ideas in this case? Any possible approach is welcome ?
    1 point
  13. @bernhard Brilliant stuff, thx. I have to dig into Tracy soon (installed, but yet not fully explored).
    1 point
  14. 1 point
  15. If you are new to hooks the linked post in my signature might be helpful ? https://processwire.com/talk/topic/18037-2-date-fields-how-to-ensure-the-second-date-is-higher/?do=findComment&comment=158164
    1 point
  16. This would be easier to explain in your context if you had included all the relevant field and template names in your post. So here is an example that you can adapt to your scenario... I have a Page Reference field named "select_colour" and generally the selectable pages are those that have the template "colour". I add this field to the template "animal", so that on animal pages I have a field to choose the colour of the animal. But in the select_colour field I only want to show colours that have not been selected on any other animal page. So in the settings for field select_colour I only use the "Custom PHP code" option for "Selectable pages" and add the following code to /site/ready.php: $wire->addHookAfter('InputfieldPage::getSelectablePages', function($event) { $page = $event->arguments(0); // Define selectable pages for the select_colour field if($event->object->hasField == 'select_colour') { /** @var Pages $pages */ $pages = $event->wire()->pages; // Find colours that are already selected on another animal page using "owner" selector // https://processwire.com/blog/posts/processwire-3.0.95-core-updates/ $already_selected_on_another_page = $pages->find("template=colour, select_colour.owner.template=animal, select_colour.owner.id!=$page->id"); // Return colour pages that aren't already selected on another page $event->return = $event->pages->find("template=colour, id!=$already_selected_on_another_page"); } }); Another possible approach is to loop over all the colour pages and remove those that are referenced on another page, but this is less specific because it will remove colours that have been referenced in any field, not just the select_colour field. $wire->addHookAfter('InputfieldPage::getSelectablePages', function($event) { $page = $event->arguments(0); // Define selectable pages for the select_colour field if($event->object->hasField == 'select_colour') { /** @var Pages $pages */ $pages = $event->wire()->pages; // All colours $colours = $pages->find("template=colour"); foreach($colours as $colour) { // Remove colour if any other pages are referencing it if($colour->numReferences) $colours->remove($colour); } // Return the filtered colours $event->return = $colours; } });
    1 point
  17. 1 point
  18. If you want to do something if the page has not yet been created: if(!$page->id) { // Do something here }
    1 point
  19. Me too, I always try to import the data using the Ryan module https://processwire.com/modules/import-pages-csv/ .. if not fit the case, then I write some code to create the pages
    1 point
  20. Perhaps you can just run your code after saving? $wire->addHookAfter("Pages::saved", /* … */); Also worth noting is the hook Pages::savedPageOrField.
    1 point
  21. Hi @Spiria The backend looks amazing. Would you please share how you make it? Gideon
    1 point
  22. Just as an addition to my post above. Maybe someone benefits from it... In a multilanguage environment the HTML5 validation prevents controll over the output on search input errors (example: when the search string is too short). It skips translated strings and always gets populated depending on the browser language settings. To disable the HTML5 validation, you must enhance the template render args for the form with the attribute novalidate. $config->SearchEngine = [ 'render_args' => [ 'templates' => [ 'form' => '<form id="{form_id}" class="{classes.form}" action="{form_action}" role="search" novalidate>%s</form>', ], ], ] With that, errors are displayed within the regular HTML Elements (which respects translated strings). I don't see any drawbacks so far. See also the comment from @teppo below!
    1 point
  23. I've never done that myself but you could also do a get request to that page automatically on save: <?php $wire->addHookAfter("Pages::saved(template=yourtemplate)", function($event) { $page = $event->arguments(0); (new WireHttp())->get($page->httpUrl); }); This might slow down saving the page for the client, but it would create all image variations for website visitors and you'd not need to define all the image variations in the hook or keep your template and the hook in sync... Happy to hear how that worked!
    1 point
  24. Hi @picarica You can achive it by hooking InputfieldFile::fileAdded like in the example below: $this->wire()->addHookAfter('InputfieldFile::fileAdded', function ($event) { $inputfield = $event->object; if ($inputfield->hasField != 'image' && $inputfield->hasField != 'images') return; $image = $event->argumentsByName("pagefile"); // Main post image if ($inputfield->hasField == 'image' && $inputfield->hasPage && $inputfield->hasPage->template->name == 'post') { $image->size('postMainImageSmall'); $image->size('postMainImageMedium'); $image->size('postMainImageMediumPortrait'); $image->size('postMainImageLarge'); } // Matrix block 'Gallery' if ($inputfield->hasField == 'images' && $inputfield->hasPage && $inputfield->hasPage->repeater_matrix_type == 5 && $inputfield->hasPage->template->name == 'repeater_builder') { $image->size('postBlockGallerySmall'); $image->size('postBlockGalleryMedium'); $image->size('postBlockGalleryLarge'); $image->maxSize(config('imageSizes')['postBlockGalleryLarge']['width'], config('imageSizes')['postBlockGalleryLarge']['width']); } // Matrix block 'Slider' if ($inputfield->hasField == 'images' && $inputfield->hasPage && $inputfield->hasPage->repeater_matrix_type == 6 && $inputfield->hasPage->template->name == 'repeater_builder') { $image->size('postBlockGallerySmall'); $image->size('postBlockGalleryMedium'); $image->size('postBlockGalleryLarge'); $image->maxSize(config('imageSizes')['postBlockSliderLarge']['width'], config('imageSizes')['postBlockSliderLarge']['width']); } // Matrix block 'Image' if ($inputfield->hasField == 'image' && $inputfield->hasPage && $inputfield->hasPage->repeater_matrix_type == 7 && $inputfield->hasPage->template->name == 'repeater_builder') { $image->size('postBlockImageSmall'); $image->size('postBlockImageMedium'); $image->size('postBlockImageLarge'); $image->maxSize(config('imageSizes')['postBlockImageLarge']['width'], config('imageSizes')['postBlockImageLarge']['width']); } });
    1 point
  25. I created this module a while ago and never got around to publicising it, but it has been outed in the latest PW Weekly so here goes the support thread... Unique Image Variations Ensures that all ImageSizer options and focus settings affect image variation filenames. Background When using methods that produce image variations such as Pageimage::size(), ProcessWire includes some of the ImageSizer settings (height, width, cropping location, etc) in the variation filename. This is useful so that if you change these settings in your size() call a new variation is generated and you see this variation on the front-end. However, ProcessWire does not include several of the other ImageSizer settings in the variation filename: upscaling cropping, when set to false or a blank string interlace sharpening quality hidpi quality focus (whether any saved focus area for an image should affect cropping) focus data (the top/left/zoom data for the focus area) This means that if you change any of these settings, either in $config->imageSizerOptions or in an $options array passed to a method like size(), and you already have variations at the requested size/crop, then ProcessWire will not create new variations and will continue to serve the old variations. In other words you won't see the effect of your changed ImageSizer options on the front-end until you delete the old variations. Features The Unique Image Variations module ensures that any changes to ImageSizer options and any changes to the focus area made in Page Edit are reflected in the variation filename, so new variations will always be generated and displayed on the front-end. Installation Install the Unique Image Variations module. In the module config, set the ImageSizer options that you want to include in image variation filenames. Warnings Installing the module (and keeping one or more of the options selected in the module config) will cause all existing image variations to be regenerated the next time they are requested. If you have an existing website with a large number of images you may not want the performance impact of that. The module is perhaps best suited to new sites where image variations have not yet been generated. Similarly, if you change the module config settings on an existing site then all image variations will be regenerated the next time they are requested. If you think you might want to change an ImageSizer option in the future (I'm thinking here primarily of options such as interlace that are typically set in $config->imageSizerOptions) and would not want that change to cause existing image variations to be regenerated then best to not include that option in the module config after you first install the module. https://github.com/Toutouwai/UniqueImageVariations https://modules.processwire.com/modules/unique-image-variations/
    1 point
  26. Hi yesjoar, Not sure about the trackChanges as Valery mentioned. But if output formatting is off, then Pw returns an array of images regardless of your max image setting. $p->setOutputFormatting(false); $image = $p->image->first(); $image->description = "Test"; $p->save() $p->setOutputFormatting(true);
    1 point
×
×
  • Create New...