Jump to content


  • Posts

  • Joined

  • Last visited

  • Days Won


Everything posted by MarkE

  1. Not sure I entirely understand the question, but it sounds like you need Hanna code.
  2. I think you’ll find that you can only use “or” when you are referencing the same field.
  3. Maybe there is something for this already in the API, or elsewhere, but I couldn't find it, so here is my suggestion. The problem is that you can't simply copy the repeater using the API in the usual way: $page2->repeater = $page1->repeater; appears to work for page 2 but messes up page1 where the repeaters get duplicated. Instead you have to copy over each of the field values within each repeater item. So I wrote this. It seems to work, at least in my context. I placed it in init.php. (However, it would be better if the core handled this more intuitively 😁) /** * Copies a repeater field to another page * Operates on the RepeaterPageArray object e.g. $page->repeater->copyTo($page2) * * @param HookEvent $event * */ wire()->addHook('RepeaterPageArray::copyTo', function ($event) { $repeater = $event->object; $repeaterField = $repeater->getForField(); $page = $event->arguments(0); if(!$page->hasField($repeaterField)) { $event->error("Field $repeaterField does not exist on page"); return; } $page->of(false); foreach ($repeater as $item) { $newItem = $page->$repeaterField->getNew(); foreach($item->getFields() as $f) { $newItem->$f = $item->$f; } $newItem->save(); $page->$repeaterField->add($newItem); } $page->save(); });
  4. Resurrecting an old post here! The reference above says "Note: we will soon support specification of page references by /path/to/page/ as well." That was a while back, but still seems not to be the case. I like to use page paths wherever possible, as it is so much easier to see what is happening (although to be safe, setting the page to 'system' may be wise as I doubt it could be made to track moves).
  5. Prompted by this, I tried using Unpoly in the back end, to achieve a bit more customisation than with pw-modal. It looks nice but loading a page edit content in an overlay seems to lose all the tabbing.
  6. I considered that, but my use case does not really need it to be configurable. I could allow superuser to configure template and parent in the module settings, but I would then need a more generic title for the setup page (presently it is “Import members from csv” so it refers to the specific context so as to be more meaningful to the user). If others wanted a configurable module, then it would not be too hard to do.
  7. Does anyone have any views on the merits of extending another module when you can't hook the required methods? I came across this recently with ImportPagesCSV. I wanted to restrict the target template and parent and then make the module accessible to a certain role (less than superuser). The buildForm1 and processForm1 methods are not hookable. Even if they were, I would have to re-use most of the code in the hook and replace the $event->return, which seems a bit messy. I guess I could hook the whole execute method, but that would be messier still. Also, the module has no permission set. Alternatively, I could suggest some additional features to @ryan, but that might take a little while to resolve. So my solution was just to extend the module with my own module - 3 methods and done. It also meant I could rename the setup page to something more specific. I've not done this before, but was very easy and seems to work well. Are there any downsides? I guess the obvious one is if some incompatible change was made to the original module and I update it, but that seems unlikely and would also affect the 'messy' hook. It seems better than hacking the original module 🙂
  8. Hi @poljpocket. It also has similarities to https://processwire.com/modules/process-db-migrate/ . That will run snippets before/after migrations. See the docs.
  9. Thanks for raising this issue @donatasand @Robin S. I was just about to consider changing a CKEditor field to TinyMCE, where the field is used in exactly this way, except that the url is inserted via a Hanna code.
  10. Absolutely! I guessed you had come across something similar. So I did an analagous edit to pwimage.js (but not specifically aimed at a repeater - the editable item might be an ordinary page, in my case in a page table). That saves having to mess with PageFrontEdit.module and is a lot simpler. I need to look more closely at the rest of the issue commentary to see what applies...
  11. I have done this by hacking PageFrontEdit.module as follows. There are two parts to the hack. Part 1 puts the id of the page being edited with the inline editor into the (hidden) tag with #Inputfield_id, rather putting the host page id there (this is what is used in the js to pick up the page id). Part 2 then partially suppresses the error that arises because the page being edited is not the host page (there may be a more elegant and safer way of doing this). I'd be grateful for any comments (esp from @bernhard) as to whether you think some change to this effect should be made you have any problems with the suggested changes or have a better idea I should raise an issue for this? Part 1 Line 429 if($hasEditTags) $numEditable += $this->populateEditTags($page, $out); - replace by $editPage = $page; if($hasEditTags) { $editTags = $this->populateEditTags($page, $out); $numEditable += $editTags['num']; $editPage = $editTags['page']; } then in lines 442 & 444 replace $this->renderAssets() by $this->renderAssets($editPage) In populateEditTags() change the return PHPDoc comment to @return array [Number of tags populated, page being edited], change the return in line 510 to if(!preg_match_all('!<' . $tag . '([^>]+)>(.*?)</' . $tag . '>!is', $out, $matches)) return ['num' => 0, 'page' => $page]; and change the return at the end of the method to return ['num' => $numEditable, 'page' => $p]; In renderAssets(), change the top to public function renderAssets($editPage = null) { if(!$editPage) $editPage = $this->page; and add the @param comment @param null|Page $editPage Then change line 853 "<input type='hidden' id='Inputfield_id' class='PageFrontEdit' value='{$this->page->id}' />" . // for CKE plugins to "<input type='hidden' id='Inputfield_id' class='PageFrontEdit' value='{$editPage->id}' />" . // for CKE plugins Part 2 In inlineSaveEdits() change lines 1077-8 from } else if($pageID != $this->page->id) { $data['error'] = "Edited page does not match current page ID ($pageID != {$this->page->id})"; to } else if($pageID != $this->page->id && !$this->pages()->find("id=$pageID, has_parent={$this->page}")) { $data['error'] = "Edited page does not match current page ID (or is not a child) ($pageID != {$this->page->id})";
  12. I think this is a bug rather than anything specific with my set-up, but it would be nice to know if anyone else has this problem. If I have a page table field in a page which is itself in a page table field and I edit the (intermediate) page containing it (in a modal), but the only change I make is the sort order of the page table items, then the save button has no effect - I need to change something else (and change it back) in order for the save to be effective.
  13. Yeah. The only thing is that other items don't automatically close (assuming you want that). Unfortunately 'name' grouping does not seem to be fully implemented yet.
  14. I have a page ('host page') with a Page Table field. The host page template is designed to render content from it and its children in the page table - a fairly standard set-up. The children have a text area field called motif_body (which I currently have set as TinyMCE, but the situation is the same with CKEditor). I am using front-end editing of this text area field, like this (in Latte): <edit page="{$page->id}" field="motif_body"> {$page->motif_body|noescape} </edit> where $page is the child page in this case. That works correctly and the child textarea field is made available for in-line editing in the front end. The problem arises when embedding images in the field. The child page also has an images field but, if 'insert image' is chosen, then the 'select image' modal shows the images on the host page, not the child page. (In my case it shows no images as the host page does not have an images field). You then have to navigate all the way through the page tree to find the child page and add the images from there. Once images are embedded in the textarea field then they are editable perfectly normally. It seems wrong to me that editing a field in the child page should look to the host page for images rather than the page the holds the field you are editing. I assume that this is because the 'image select field' in the modal is defaulting to the page which is open in the page editor rather than the page which holds the field being edited. Is this the intentional behaviour and, if so, why? In any case, is there a way of making the image select field pick up the 'right' page?
  15. I think that's right @gornycreative. I hit this problem with htmx and repeaters - this was my solution: // To make sure that hx- attributes fire in lazy-loaded repeater fields $(document).on('reloaded', '.InputfieldRepeater', function (event) { htmx.process(this); })
  16. @TomPich: You also want to give some careful thought to managing the access to practitioner pages.
  17. You might want to use the BatchChildEditor module for this.
  18. Thanks @matjazp. The issue is well-documented there. In my case, it ocurred after a database load and a modules refresh (not a PW update). I suspect the issue was caused by loading a database from a later PW version (3.0.229). I removed the rows from the modules table and all seemed OK after that. I then updated to 3.0.235 and the rows are back in the table, but no errors are shown. So it appears to not be a bug as such (or at least is fixed) but will probably still happen if someone downgrades or loads a database to an older PW version.
  19. .. or even taking advantage of newer html5 developments. For example, <details><summary>. I guess the fundamental issue is that this is always a moving target, so it makes sense to not try and track the latest fashion, but to move when it is clear that the way forward is established and generally accepted.
  20. Do you have dynamic loading on?
  21. I kept getting these errors on my modules page on one site I have no such modules listed, but inspection via Adminer shows that they have entries in the modules database. Each entry has data listing a number of modules, such as (for .ModulesVerbose.info). 178 summary Tracy debugger from Nette with many PW specific custom tools. author Adrian Jones href https://processwire.com/talk/forum/58-tracy-debugger/ versionStr 4.23.33 I assumed that the database got corrupted somehow (but how?), so I deleted the entries. Everything seems to be OK.... Any ideas what might have caused this? Anyway, thanks @adrianfor Adminer - always useful in extremis.
  22. Hmm. Thanks @Robin S. I had already tried something similar with no success. I tried your hook, but it doesn't seem to get triggered in the particular circumstances I described (i.e. when the field is not added to the templates, just included as a column). UPDATE: However, $wire->addHookBefore('FieldtypeRuntimeOnly::markupValue', function(HookEvent $event) seems to do the trick In fact, since I was using a forked hacked version of your module anyway, it was simpler to add $inputfield = $field->getInputfield($page); $inputfield->renderReady(); in markupValue() - just before return $this->renderMarkup($page, $field); 😀
  23. OK - a really simple solution if you only concerned about one Page Table Field on the relevant pages. In my case, this is in the context of a module, where the name of the Page Table field is 'motif_block_table'. In the module's ready(): $this->addHookAfter('Pages::moved', $this, 'afterPagesMoved'); then: protected function afterPagesMoved(HookEvent $event) { $page = $event->arguments(0); $oldParent = $page->parentPrevious; $newParent = $page->parent; if($oldParent->id == $newParent->id) return; if($oldParent->hasField('motif_block_table')) { $oldParent->motif_block_table->remove($page); $oldParent->setAndSave('motif_block_table', $oldParent->motif_block_table); } if($newParent->hasField('motif_block_table')) { $newParent->motif_block_table->add($page); $newParent->setAndSave('motif_block_table', $newParent->motif_block_table); } } So now I have only one operation - namely to move the page in the page tree - and both fields get reset accordingly (although it may be necessary to re-sort the receiving page table as the new child will be added at the end, regardless of where you drag it in the tree). NB this will not work unless your page naming ensures unique names, as there is a risk that the new parent already has a page with the same name as the one you are moving and the move will be forbidden until you rename one of them. This could easily be generalised to operate outside of a module. It could also be adapted to refer to an unspecific Page Table field, provided there is only one. If there is more than one Page Table field and you want to track moves, it gets a bit trickier: finding the field to remove the page from is easy enough; then you either need to do something clever in js to select which field it is added to, or else (probably simpler) just go to the page and add the new child to the relevant field.
  • Create New...