Jump to content


  • Posts

  • Joined

  • Last visited

  • Days Won


Everything posted by psy

  1. Had an extreme example to deal with recently. Multiple field replacements for various fieldtypes. May not be the best approach but worked for me. Private function is in a custom module function. <?php /** * Takes a page field, eg 'body' as a template and replaces tags eg {age} with the same field value * from the supplied data page * @param $tplPage * @param $tplField * @param $dataPage * @param string $startTag * @param string $endTag * @param array $other * @return string|string[] * @throws WireException * @throws WirePermissionException */ private function _compileFieldTags ($tplPage, $tplField, $dataPage, $startTag = '{', $endTag = '}', $formatDate = false, $other = []) { $allowedFieldtypes = [ 'FieldtypeText', 'FieldtypeTextarea', 'FieldtypeInteger', 'FieldtypeFloat', 'FieldtypeDatetime', 'FieldtypeToggle', 'FieldtypeCheckbox', 'FieldtypePage' ]; $replacementNames = []; $replacementValues = []; // Sort out what to do with each inputfield type foreach ($dataPage->fieldgroup as $replacement) { if (!in_array($replacement->type, $allowedFieldtypes)) continue; switch ($replacement->type) { case 'FieldtypeDatetime': $fldData = $formatDate == false ? $dataPage->$replacement : $dataPage->getFormatted($replacement); break; case 'FieldtypePage': $fldData = $dataPage->$replacement->title; break; case 'FieldtypeCheckbox': $fldData = $dataPage->$replacement == true ? "Yes" : "No"; break; default: $fldData = $dataPage->$replacement; break; } $replacementNames[] = $replacement->name; $replacementValues[] = $fldData; } // Prepare replacement arrays foreach ($dataPage as $k => $v) { $replacementNames[] = $startTag . $k . $endTag; $replacementValues[] = $v; } $replacementNames['url'] = $startTag . 'url' . $endTag; $replacementValues[] = $dataPage->httpUrl; $result = str_ireplace($replacementNames, $replacementValues, $tplPage->$tplField); return $result; }
  2. Trying to upgrade TD to the latest version and I get this: Fatal Error: Uncaught WireException: No download URL specified in wire/modules/Process/ProcessModule/ProcessModule.module:1072 Happens both on the Modules->New and Settings->Upgrades with the upgrade module. I could upload the zip but that's not the issue. Reason for upgrade was another error message: Fatal error: Uncaught Exception: Serialization of 'Closure' is not allowed in [no active file]:0 Stack trace: #0 {main} thrown in [no active file] on line 0 which auto-magically began appearing. I'm not serializing any data and the error disappears when I turn off TD. Any ideas on what's happening here?
  3. @Knubbi that's a question for Ryan in the ProDrafts forum 🙂
  4. If it's only content, there's also https://modules.processwire.com/modules/version-control/
  5. @MoritzLost True, however (unless I missed something), ProDrafts doesn't work for Repeater Matrix whereas my suggestion will work for template development. As I understand it, ProDrafts is more for checking/comparing content before committing changes. I guess it's what @Knubbi is trying to do
  6. You could use site/config .php settings, eg: <?php if ($user->hasRole('dev') { // or whatever role you assign // development templates directory $config->urls->templates = $config->urls->site . 'templates-dev/'; $config->paths->templates = $config->paths->site . 'templates-dev/'; $config->urls->fieldTemplates = $config->urls->templates . 'fields/'; $config->paths->fieldTemplates = $config->paths->templates . 'fields/'; } // other users, including the public, will see the default $config->templates & $config->paths (same for fields)
  7. Some things to try as results can vary depending on the PHP version: Be more explicit in your if statement, and turning off outputting formatting: <?php if(!empty($page->myfield_text_a) && !empty($page->myfield_text_b) && !empty($page->myfield_options) && !empty($page->myfield_date)) { $page->of(false); //.... }
  8. Some things to check which tripped me up when taking over from a previous developer: In site/config.php ensure that the template url & path are pointing to YOUR templates url & path. The default is 'template' however is customisable In Set Up ->Templates -> [your template] -> Files tab, that your template file name is not being overridden in the Alternate File Name field by something the original dev entered HTH
  9. Had the same issue as @LAPS, ie $vars not accessible in the rendered template. Fixed by including an empty array for $options, ie: <?php $vars = [ 'items' => $items, 'homepage' => pages(1), 'category' => $category ]; echo $files->render('inc/item-detail',$vars,[]);
  10. OK @AndZyk get it after the explanation but a bit confusing without that knowledge. The cursor changing to a text selector on edit threw me. Maybe turn off pointer events to let the user know it's just a display thing?
  11. @AndZyk great work. 👏 Only other feedback I have is that the buttons "What do I see?", "What do I hear" & "How does the hustle & bustle affect me?" don't go anywhere/show anything. My cursor changed from normal arrow to an 'edit' icon, not pointer on hover. Is this supposed to happen? I'm using Chrome on an iMac
  12. Check the id's of each form & its submit button If they're the same for both and depending on your embed method, both will submit when either form is submitted. Had a similar issue a while ago and changing the form ID's to be unique helped. See
  13. Thanks @SIERRA Oops! Just re-read my code and noticed a mistake. Should be: <?php if (!empty($input->get->id) { // PW way of accessing $_GET $id = $sanitizer->int($input->get->id); // Clean it up to ensure it's an integer $alertspage = $pages->get($id); // You can also do $pages->get("id=$id") if (!$alertspage instance of NullPage) { // ensure the page exists echo $alertspage->title; } else { echo "There was a problem retrieving the page with ID $id"; } } Missed the curly braces surrounding the first and last lines
  14. Think the issue may be in this line - no $ in front of id. Try: <?php if (!empty($input->get->id) // PW way of accessing $_GET $id = $sanitizer->int($input->get->id); // Clean it up to ensure it's an integer $alertspage = $pages->get($id); // You can also do $pages->get("id=$id") if (!$alertspage instance of NullPage) { // ensure the page exists echo $alertspage->title; } else { echo "There was a problem retrieving the page with ID $id"; }
  15. @Robin S Brilliant! Not quite what I needed but a great starting point. My scenario was: Didn't know the repeater item id Did know the id of a particular (page) field inside the repeater page And wanted any repeater item with that field id to be locked for editing by all, including super users. Here's what worked for me: <?php $wire->addHookAfter('Field::getInputfield', function(HookEvent $event) { $page = $event->arguments(0); if (!$page instanceof RepeaterPage) return; $inputfield = $event->return; // Only for a particular Repeater page field (fieldtype page) ID if($page->my-page-field->id !== 4486) return; // Set collapsed to Inputfield::collapsedNoLocked or Inputfield::collapsedHidden as suits $inputfield->collapsed = Inputfield::collapsedNoLocked; });
  16. Hi @SIERRA Using pure PW, you can go to Pages ->Find (in the dropdown), select your repeater template then add any other filters, eg Title - Contains Text...
  17. I know that headless cms has been a hot topic for a while. I've experimented with several frontend frameworks (Angular, React, Vue, etc) and I just don't get it. Maybe for huge corporations with multiple dev teams and big budgets, OK. For 95+% of use cases however, I find headless cms/js frontend to be a major pain with no discernible benefits. From a frontend web UX, they're often slower than a well built PW site with caching (eg ProCache). For native apps, something like api calls to/from PW/Dart via json would do the job. Am I missing something other than a desire for JS devs to earn extra $$$?
  18. @jploch Does this help? On the Template -> Edit -> Files tab, you could nominate an alternative template/path for your PageTable template.
  19. Not sure if related to your issue, but shouldn't that be a double = after $template?
  20. @bernhard Grateful for the offer to help, however on a tight schedule and managed to get the solution to my query using a normal PW selector with the very helpful and hard to find gem "repeater_field.owner.field_name'. It enabled me to get the repeater field, it's originating page and the individual repeater item data. The selector returns a WireArray of repeater fields which are then manipulated into a flat array for RockTabulator. From what I could see in the SQL statement from RF3, the field table aliases are getting mixed up when both the first and main RF3 queries have the same field name, eg 'title' - some have the unique id twice and then the LEFT JOIN 'title' gets the wrong one which then fails.
  21. Same result. I tried that first before changing the column name to 'booking'
  22. Don't know what I'm doing wrong but cannot join two RF3 statements when both have the field 'title'. I based it on the example of: <?php $owners = $rockfinder ->find("template=person") ->addColumns(['title', 'age']) ->setName('owner'); // set name of target column $rockfinder ->find("template=cat") ->addColumns(['title', 'owner']) ->join($owners) ->dump(); My case is field 'booking_status' is a page reference field in template 'booking'. <?php $rockfinder = modules("RockFinder3"); $booking_status = $rockfinder ->find("parent.id=1154, include=all") ->addColumns(['title']) ->setName('booking_status'); $rockfinder ->find("template=booking") ->addColumns(['title'=>'booking', 'booking_status']) ->join($booking_status) ->dump(); Each one individually returns the correct data. However when I try to use the join, it errors with "SQLSTATE[42S02]: Base table or view not found: 1146 Table 'xxxxx_xxxx.field_title_5ee33d16934fa' doesn't exist". Both templates have a 'title' field. The SQL dump is: "SELECT `pages`.`id` AS `id`, `_field_title_5ee33bf3cb7d8_5ee33bf3cb854`.`data` AS `booking`, GROUP_CONCAT(DISTINCT `_field_booking_status_5ee33bf3cb92f`.`data` ORDER BY `_field_booking_status_5ee33bf3cb92f`.`sort` SEPARATOR ',') AS `booking_status`, GROUP_CONCAT(DISTINCT `join_booking_status_5ee33bf3cbbbe`.`title`) AS `booking_status:title`, GROUP_CONCAT(DISTINCT `join_booking_status_5ee33bf3cbbbe`.`booking`) AS `booking_status:booking`, GROUP_CONCAT(DISTINCT `join_booking_status_5ee33bf3cbbbe`.`booking_status`) AS `booking_status:booking_status` FROM `pages` LEFT JOIN `field_title_5ee33bf3cb7d8` AS `_field_title_5ee33bf3cb7d8_5ee33bf3cb854` ON `_field_title_5ee33bf3cb7d8_5ee33bf3cb854`.`pages_id` = `pages`.`id` LEFT JOIN `field_booking_status` AS `_field_booking_status_5ee33bf3cb92f` ON `_field_booking_status_5ee33bf3cb92f`.`pages_id` = `pages`.`id` LEFT JOIN ( SELECT `pages`.`id` AS `id`, `_field_title_5ee33bf3cb5c3`.`data` AS `title`, `_field_title_5ee33bf3cb7d8_5ee33bf3cb854`.`data` AS `booking`, GROUP_CONCAT(DISTINCT `_field_booking_status_5ee33bf3cb92f`.`data` ORDER BY `_field_booking_status_5ee33bf3cb92f`.`sort` SEPARATOR ',') AS `booking_status` FROM `pages` LEFT JOIN `field_title` AS `_field_title_5ee33bf3cb5c3` ON `_field_title_5ee33bf3cb5c3`.`pages_id` = `pages`.`id` LEFT JOIN `field_title_5ee33bf3cb7d8` AS `_field_title_5ee33bf3cb7d8_5ee33bf3cb854` ON `_field_title_5ee33bf3cb7d8_5ee33bf3cb854`.`pages_id` = `pages`.`id` LEFT JOIN `field_booking_status` AS `_field_booking_status_5ee33bf3cb92f` ON `_field_booking_status_5ee33bf3cb92f`.`pages_id` = `pages`.`id` WHERE (pages.templates_id=53) AND (pages.status<1024) GROUP BY pages.id ) AS `join_booking_status_5ee33bf3cbbbe` ON `join_booking_status_5ee33bf3cbbbe`.`id` = `_field_booking_status_5ee33bf3cb92f`.`data` WHERE (pages.templates_id=53) AND (pages.status<1024) GROUP BY pages.id " (1933) in .../RockFinder3/RockFinder3.module.php:504 I can add any field in the "template=booking" statement EXCEPT 'title'. Using 'addRelationship' is even worse. It errors with PHP out-of-memory. Using RF3 v1.0.7 and PW 3.0.158 Help appreciated.
  23. Thanks for liking @bernhard Another tip... not only doesn't it work, but who wants multiple CSS files for a repeater? In this scenario, the page template had another RM2 field - simple field on the main template. All CSS for the repeater RM2 field went into the other RM2 field's CSS file, not the repeater field's CSS. I'm sure there are other ways to get the RM2-in-a-repeater's CSS to work - just needs thinking outside the square 😉
  24. I realise this module is deprecated but it is in use on a site I'm working on. I needed to add a RM2 field into a repeater and it didn't work due to the unique nature of repeaters. A little hack to RM2 Inputfield module solved 2 problems at once. The Inputfield works in repeaters AND the repeater item ID is accessible in the parent page via the $session var. <?php /** * Set the field content from the file with the same name */ public function ___getContent() { $out = ''; // get file $name = $this->name; /****** hack - breaks on repeater fields ******/ if (strpos($name,'_repeater') !== false) { // it's in a repeater field $ary = explode('_repeater', $name); $name = $ary[0]; // save the repeater item ID with the original fieldname as the key for future use wire('session')->set($name, $ary[1]); } /****** end of hack - breaks on repeater fields ******/ $file = $this->main()->getFile($name); if(!$file) return "No file found for field $name"; // if a value was set return it if($this->value) $out = $this->value; else { // otherwise try to render the file try { // get page object $page = $this->page; if($this->process == 'ProcessPageEdit') { $page = $this->process->getPage(); } // get markup $out = $this->files->render($file->path, [ 'inputfield' => $this, 'rm' => $this->rm, ], [ 'allowedPaths' => [$file->path], ]); } catch (\Throwable $th) { $out = $th->getMessage(); } } return $out; } It's a bit rough but it works for me and maybe this tip can help others working with repeater fields.
  25. @kongondo It's related to RockFinder3. Posted in the wrong place
  • Create New...