-
Posts
4,928 -
Joined
-
Days Won
321
Everything posted by Robin S
-
Cloning pages seems to have different effects
Robin S replied to louisstephens's topic in General Support
It's annoying, right? You could thumbs-up the existing request for a change to this behaviour: https://github.com/processwire/processwire-requests/issues/186 And as a workaround in the meantime try this hook in /site/ready.php: $wire->addHookAfter('ProcessPageListActions::getExtraActions', function(HookEvent $event) { $page = $event->arguments(0); $actions = $event->return; if(isset($actions['copy']['ajax'])) { unset($actions['copy']['ajax']); $actions['copy']['url'] = "{$this->config->urls->admin}page/clone/?id={$page->id}"; } $event->return = $actions; }); If you find it's not working for you then it might be getting called before the equivalent hook inside ProcessPageClone, in which case you could try experimenting with the "priority" option for hooks: https://processwire.com/api/ref/wire/add-hook-after/ -
There are also specific elements within the $page->render() $options array for prependFile and appendFile, see here. So you can do: foreach($page->children('template=child') as $child) { echo $child->render(['prependFile' => null, 'appendFile' => null]); }
-
Repeated frontend login errors cause 500 internal server error
Robin S replied to Gideon So's topic in General Support
You have to handle the login throttle exception: -
Hi @tpr, a feature request: could you add a cache-busting query string (e.g. using filemtime) to the assets added from the "Asset Paths" section of AOS? Thanks!
-
My regex is rather weak also, but I think this will work... $cc = $modules->get('ServiceCurrencyConversion'); $text = $page->body; $regex = '/\x{20AC}([0-9]+\.?[0-9]+)/u'; $text = preg_replace_callback( $regex, function($matches) use ($cc) { $dollars = number_format($cc->convert('EUR', 'USD', $matches[1]), 0); return "{$matches[0]} (\${$dollars})"; }, $text ); echo $text; Would makes sense to put this into a simple Textformatter module and use it that way. See TextformatterNewlineBR for a basic example to start from.
-
Hi @bernhard, A bit OT, but in your development of this module have you had the need yet to get the path or URL of the pages you are including in a query? Do you know a way of getting or constructing the page path/URL from the database data without getting Page objects involved? From a quick investigation it looks like PW builds the path/URL with methods in the Page class but I was hoping to avoid having to load Page objects. Any tips?
-
Acces multilang field values inside processInput Hook
Robin S replied to Andreas Augustin's topic in General Support
@Andreas Augustin It's interesting - if you dump/log the $value here directly in InputfieldTextarea::processInput you can see that the method is called for every language. However, you can only actually hook the call for the default language - for the other languages the method must be called in such a way that hooks are not triggered (by calling the method name with the three underscores included). So you'll probably have to get the other language values from $input (either the WireInput argument to the method or via the API $input variable). For example... $wire->addHookBefore('InputfieldTextarea::processInput', function(HookEvent $event) { $inputfield = $event->object; $input = $event->arguments(0); if(!$inputfield->hasField || $inputfield->hasField != 'your_field_name') return; // The value for the default language $default_language_value = $inputfield->value; // The value for French language $french = $this->languages->get('french'); $input_var_name = "{$inputfield->name}__{$french->id}"; $french_value = $input->$input_var_name; // ... }); -
@BillH, I can't reproduce the issue. For me the module is working as expected for non-superusers. The list of files is generated in the ajaxResponse() method. To debug you could use Tracy Debugger (best option) or $log to check that the method is firing and is returning JSON for files on the page. Edit: if you updated from an earlier version of the module you might need to do a hard refresh in case the browser is caching the old version of plugin.js - not sure if CKEditor itself does any kind of cachebusting and there is no way to do this within the module for CKEditor plugins.
-
Nice site! One thing: to avoid blurry text in Chrome you could change instances of... transform: translate3d(-50%,-50%,0); ...to... transform: translate(-50%,-50%); ...if you're not actually using 3D space. Before: After:
-
Matching 2 pages based on title and "combining" data
Robin S replied to louisstephens's topic in API & Templates
You'd need to put more of the markup inside the conditional, otherwise it will be output for each iteration of the foreach. But for more nested markup like this it will be easier to make sense of if you first loop over all the service pages and build an associative array to group the services by person, then loop over the array. <?php $services = $pages->find("template=service-a|service-b, sort=parent.name, sort=sort"); // Group the services by person $people = []; foreach($services as $service) { $people[$service->parent->title][] = $service; } // Take a look at $people using Tracy Debugger just to understand what is going on bd($people, 'people'); ?> <?php foreach($people as $name => $services): ?> <div class="user"> <h3><?= $name ?></h3> <ul> <?php foreach($services as $service): ?> <li><?= $service->title ?></li> <?php endforeach; ?> </ul> </div> <?php endforeach; ?> -
Could be done, but I think there are probably better solutions already available such as AvbImage and PageImage Manipulator.
-
Acces multilang field values inside processInput Hook
Robin S replied to Andreas Augustin's topic in General Support
I don't normally deal with multi-language so I'm not sure if this is the best way, but it seems to work... public function validateShortlinks($event) { $field = $event->object; // Get specific language value $french = $this->languages->get('french'); $french_value = $field->get('value' . $french->id); // Or loop over all languages foreach($this->languages as $language) { $value = $field->get('value' . $language->id); //... } } -
Programmatic manual sorting of page reference pages
Robin S replied to Martin Muzatko's topic in General Support
It is neither built-in nor is it a field - it is just a custom property that you are setting to a page object while it is in memory. You can name the property anything you like - it doesn't need to be named "custom_sort". The "custom_sort" is not saved to the database for any page - it only exists while the page is in memory, and it's purpose is simply to provide some property to use the sort() method on. Then once the PageArray is sorted on that property and saved to the Page Reference field the sort is retained as part of the Page Reference field value. If you just give it a go it will probably start to make more sense. -
Great, thanks. Enjoy your holiday!
-
I had a quick look and validating the form is straightforward. After the form input is processed... if(count($form->getErrors())) { // There were some form errors so do not proceed with action } But at this point we are already in executeExecute() because the action of the form is the execute URL segment, and the page headings are different in this method. Maybe it would be better if the action of the options form was options URL segment, and then if successful redirect to execute segment? Not sure, there are probably several different ways to handle it and I'm sure you'll know the best approach.
-
Hi @adrian, I have a request for an enhancement to this module. I think it would be useful if the options form for an action was validated before executeAction() fires. So the required/requiredIf conditions are evaluated and executeAction() only fires if the form submission is successful. At the moment executeAction() fires even when the required/requiredIf conditions are not met, which means you have to do extra validation inside executeAction() and that can get quite tricky with some requiredIf setups. What do you think?
-
Programmatic manual sorting of page reference pages
Robin S replied to Martin Muzatko's topic in General Support
What is causing you to draw this conclusion? The value of a (multiple) Page Reference field is a PageArray. The sort order of pages in the field will be the sort order of the pages in the PageArray at the time the field (or the whole page containing the field) is saved. So setting the sort order of the field consists of putting the pages in the PageArray into the order you want and then saving the field (or the whole page containing the field). So if I have a Page Reference field "colours" which is currently empty on page $p and I add some pages to the field then the order is the order in which I add them (to the PageArray)... $p->of(false); $yellow = $pages->get('name=yellow'); $p->colours->add($yellow); $red = $pages->get('name=red'); $p->colours->add($red); $blue = $pages->get('name=blue'); $p->colours->add($blue); $p->save('colours'); // Alternatively you could save the whole page // Sort order of $p->colours is yellow, red, blue Suppose I now want to change this sort order to some other custom order. Let's say I want to sort them by the length of the page name. $p->of(false); foreach($p->colours as $colour) { $colour->custom_sort = strlen($colour->name); } $p->colours->sort('custom_sort'); $p->save('colours'); // Alternatively you could save the whole page // Sort order of $p->colours is red, blue, yellow -
Matching 2 pages based on title and "combining" data
Robin S replied to louisstephens's topic in API & Templates
As a general observation, I think using the page title or page name as a way to connect different pages to a single person is not very robust. It would be better to have a separate section in your page tree for "Persons", with John Doe, Jane Doe, etc, stored under there. Those pages don't necessarily have to appear on the front-end or have a template file. Then other pages are connected to a person by a Page Reference field. But on to your question... If it is acceptable to sort the persons listing by the name of the person then you could do this... $services = $pages->find("template=service-a|service-b, sort=parent.name"); $name = ''; foreach($services as $service) { if($service->parent->name !== $name) { // This service is from a different person, so output a heading echo "<h3>{$service->parent->title}</h3>"; $name = $service->parent->name; } echo "<p>$service->title</p>"; } Note that if you were using a Page Reference field to link services to a person then you would have more sorting options available to you - i.e. you could sort by any field that exists in the person template. -
Wow, that truncate function will truncate my search for the ultimate truncate function! ? I wonder if the default for the "visible" option should be true rather than false. If my string included entities and markup tags I think in nearly all cases I wouldn't want those invisible items affecting the visible string length.
-
It's just like @kongondo said - you have to save a new page before you can add files or images to it. The directory needed to hold the files/images gets created on the first save - then you can add files/images. So in submit(), do $p->save() before setDummyData()... public function submit() { $input = $this->wire('input'); $page = $this->wire('page'); $session = $this->wire('session'); if ($input->post->submit && $this->canEdit()) { if (($p = $this->savePageBasic()) !== false) { $p->addStatus(Page::statusHidden); $p->save(); $this->setDummyData($p); } $session->redirect($page->path); } } P.S. This... $parent = $this->wire('pages')->get($page->path); $p->parent = $parent; ...could be better optimised as... $p->parent = $page;
-
Exclude "page copying" from addHookAfter("saved")
Robin S replied to chumneypwire's topic in API & Templates
A couple of different ways... $pages->addHookAfter('saved', function(HookEvent $event) { $page = $event->arguments(0); if($page->hasStatus('unpublished') || $page->hasStatus('trash')) return; // Your code... }); $pages->addHookAfter('saved', function(HookEvent $event) { $page = $event->arguments(0); if($page->isUnpublished() || $page->isTrash()) return; // Your code... });- 3 replies
-
- copying
- addhookafter
-
(and 2 more)
Tagged with:
-
@PWaddict, I agree with @kongondo. If page A has a single page reference field with page B selected in it then page B must not have a single page reference field with page A selected in it. This only applies to two single page reference fields - if one or both are multiple page reference fields then there is no problem. This isn't an issue with this module specifically, just a limitation of PW. Related GitHub issues: https://github.com/processwire/processwire-issues/issues/152 https://github.com/processwire/processwire-issues/issues/572
-
If you are able to log in you may be able to resolve the errors by rebuilding the modules cache at Modules > Refresh. Related topic:
-
Exclude "page copying" from addHookAfter("saved")
Robin S replied to chumneypwire's topic in API & Templates
I think ProcessPageClone should give the user an opportunity to specify a title and name for the page before the clone is done, as is the case for cloning pages with children. I opened a request for this. But in the meantime you could check to see if a sibling page exists with the same name as the cloned page excluding the "-1" suffix. $base_name = rtrim($page->name, '-1'); if($page->siblings("name=$base_name", false)->count()) return; Edit: or maybe a better approach is not to write to your CSV for unpublished pages, as cloned pages are unpublished at first.- 3 replies
-
- 2
-
- copying
- addhookafter
-
(and 2 more)
Tagged with:
-
@adrian, maybe the module needs a try/catch to show the login throttle message rather than the 500 error?