Jump to content


  • Posts

  • Joined

  • Last visited

Recent Profile Visitors

The recent visitors block is disabled and is not being shown to other users.

rastographics's Achievements

Full Member

Full Member (4/6)



  1. Very cool Ryan. Thank you for this, I never used functional fields before but they sound perfect for a use case I have right now.
  2. For handling datetime in Processwire, I've come to realize that the best way for me to avoid the most headache is leave EVERYTHING in UTC...the $config file, the ddev settings, etc. Then whenever I need to display times on the front end, I use a helper function I created that formats time in the Timezone of my choosing, at display time. With this method, the production server timezone or my dev environment timezone never matters. The added benefit is that you can have users save a timezone to their profile and then display times in their timezone. Any other way of dealing with timezone besides saving UTC to database has always created a mess for me later down the road. function UtcToCst($timestamp) { if(!$timestamp) return; return (new \DateTime("@" . $timestamp))->setTimezone(new \DateTimeZone("America/Chicago")); //Or use a timezone saved on your $user template. }
  3. Thank you for the site profile and especially the blog post and extensive comments throughout the code. It's extremely helpful for overall architecture examples, which is something hard to find by just reading documentation or searching forum, because recommended practices have changed over the years. Especially love learning how you do things in the admin side for customizing the page edit screens, etc.
  4. Solved w/ Hacky Workaround: By adding a line of code to InputfieldImage.js, I'm able to now specify a url to POST to when using AJAX upload for InputfieldImage. //LINE 1635 of InputfieldImage.js function initHTML5Item($this, i) { //THIS CODE IS UNMODIFIED >>> var $form = $this.parents('form'); var $repeaterItem = $this.closest('.InputfieldRepeaterItem'); var postUrl = $repeaterItem.length ? $repeaterItem.attr('data-editUrl') : $form.attr('action'); // <<<<<< THIS CODE IS UNMODIFIED /* To get InputfieldImage to work on a page besides the ProcessEditPage We need to change the POST url for ajax uploading of images, to point to the EditUrl of the page that contains the image field. We can set the custom action url on the form html element. But we need to grab that value here if it exists. */ //THIS LINE WAS ADDED BY JOEL TO MAKE INPUTFIELDIMAGE WORK ON OTHER PAGES.... if($form.attr("ajax_action")) postUrl = $form.attr("ajax_action"); //THIS CODE IS UNMODIFIED >>> postUrl += (postUrl.indexOf('?') > -1 ? '&' : '?') + 'InputfieldFileAjax=1'; And in my custom admin module, I add this attribute to the form that contains the image field... /* AJAX Image uploads. Set a custom ajax POST url here that will be used in the core InputfieldImage.js file to have the correct upload url for ajax images on the InputfieldImages. */ $form->attr("ajax_action",$mypage->editUrl); Now it works flawlessly! (Don't forget to add "<div style='display:none' id='PageIDIndicator'>$mypage->id</div>" someone on the page too! as mentioned in previous post)
  5. I create a simple Process module that retrieves specific pages and displays them one at a time on an "Edit" page. The edit page contains a form like so: $form = modules()->get('InputfieldForm'); $form->add($myPageToEdit->getInputfield('my_image_field') $form->add($aRelatedPage->getInputfield('my_text_field') I also add a submit button and some other fields for editing that are not relevant. `my_image_field` is an image field. When this custom edit page is displayed (in the admin, a url like examplesite.com/admin/my-module/edit?id=2494), the form shows up fine. If the image field is populated, then the existing image displays correctly. Using the form to edit the text fields (or even repeater fields) works great. But the image field on this custom module has broken behavior. First of all the Ajax Upload functionality is disabled. I figured out it is because of this code in InputfieldImage.js: /** * Whether or not AJAX drag/drop upload is allowed? * * @returns bool */ function useAjaxUpload() { var isFileReaderSupport = window.File && window.FileList && window.FileReader; var isAjaxUpload = $('.InputfieldAllowAjaxUpload').length > 0; var isPageIDIndicator = $("#PageIDIndicator").length > 0; //THIS ELEMENT DOES NOT EXIST ON MY MODULE'S PAGE SO AJAX UPLOAD GETS DISABLED??! return (isFileReaderSupport && (isPageIDIndicator || isAjaxUpload)); } Because it is looking for #PageIDIndicator, which doesn't exist, then ajax gets disabled? So I have to work around by adding that element to my page like we find in ProcessPageEdit.module (Line 640) $out .= "<div id='PageIDIndicator' class=''>{$this->page->id}</div>"; So on my module I add <div id='PageIDIndicator'>3423</div> where 3423 equals the page id. NOW Ajax Upload is enabled. But it is very broken. Because the functionality to process the ajax upload is in ProcessPageEdit only, and it is expecting a JSON response...but the form needs to postback to my custom module edit page, which doesn't know how to respond to AJAX and specifically process the InputfieldImage upload. So it seems like the AJAX upload functionality is baked into ProcessPageEdit, and so the InputImageField was not designed to be used anywhere in the admin except on ProcessPageEdit? Something tells me there has to be a way to configure the InputImageField in my form to work in a custom module for Ajax uploads? By the way, Non-ajax uploads work with no problem from my custom module. But they are very unintuitive and limited to one photo at a time. Deletes also work.
  6. Yes! And reading that while being a little frustrated with the way I'm currently doing htmx and processwire
  7. Thanks @cwsoft and @zoeck. I've used custom page classes for a while but I don't think to full potential so I'm sure these resources will get me to the next level of what is possible. My reason for coming to this thread is I'm trying to have a more elegant way of using htmx by using "partials" on the php side, and I read that latte will let me break the html up into partials better than the regular php templates. Excited to hopefully use latte to make the htmx experience better. And just overall structure my processwire projects better.
  8. I want to do this to my projects too. What resources did you use to learn how to do this @cwsoft? Or is any of your code shareable? Thank you!
  9. $tomorrow1AM = strtotime("tomorrow 1:00"); echo cache()->renderFile("chunks/home/birthday.php", $tomorrow1AM); This code works fine if I use a WireCache constant for the expire parameter. But if I use a timestamp, as shown above, the cache doesn't work. The cached does get "created" (verified by looking in TracyDebugger) with an expire time of 1am the next day. However, the page is still loading 1700 pages of content, and taking 800ms to execute, as opposed to 53 pages of content and 90ms to execute when the cache is correctly getting used. So it seems that $cache->renderFile is saving the cache, but not hitting it on future loads in my case. Do you have any insight? Any other information I need to share?
  10. For now I'm doing this on line 271 of AppApi/classes/Auth.php . But I have to be careful when updating the module now. /* ADDED TO GIVE JWT ACCESS TOKEN A DIFFERENT SESSION LENGTH THAN REGULAR SITE LOGINS */ $config = $this->wire('config'); $expireSeconds = $config->sessionExpireSeconds; if(isset($config->appApiSessionExpireSeconds)){ $expireSeconds = $config->appApiSessionExpireSeconds; } $apptoken->setExpirationTime(time() + $expireSeconds);
  11. @Sebiwould you be open to a pull request that adds a new setting? Access Token Expires In? I see that the access token uses the $config->sessionExpireInSeconds value for the access token expiration. However, using JWT, I would like to have a shorter (60 minutes) session, because of using the Refresh Token to keep things logged in. For the rest of my site (not using AppApi), the normal users I want to have 24 hour session, which I set with $config->sessionExpireInSeconds. There is already an Expires At setting in AppApi, for Refresh Token. Is it okay to add a second Expires At setting for Access Token, in case we want to set a different expiration from rest of site? Hope this makes sense?
  12. For Double JWT approach, have you considered sending tokens to client using httpOnly cookie? I'm not an expert on this topic, but when researching to see where to save the tokens in my app, it seems the opinion for most secure involves httpOnly cookie (among other things). One such conversation: https://stackoverflow.com/questions/27067251/where-to-store-jwt-in-browser-how-to-protect-against-csrf?rq=1 Do you currently use localstorage on the browser? I'm creating a new app. Your module is awesome. But I'm wondering if localstorage is most secure on client? And how to do httpOnly cookie with this module?
  13. Unfortunately I just tried that code and it does not work. Because trash() checks isDeletable() which checks if the page to delete is the current page, this code does not get around that situation. It will only work on processwire installations that were installed before the hardcoded date in 2019 when the core was changed.
  14. I made a new issue that is more specific. The issue is not limited to superuser. It is more specific in that the trashable() method is calling deleteable() which checks if page is the current page. https://github.com/processwire/processwire-issues/issues/1693 I think that trashable() should not be checking if page is the current page.
  15. UPDATE: I noticed I can trash these pages through the api as long as do it from other pages. In other words, it is impossible to trash the current page. I found this github issue where someone pointed out that the behavior changed in this commit to not allow current page to be deleted. This only happens on PW installs that happened after a hard-coded date, so maybe why not many people run into this? I didn't see behavior (current page cannot be deleted) documented in the $pages or $page api. In the code of the commit, there are clear error messages returned. Here is the message for trying to delete the current page: "it is the current page being viewed, try \$pages->trash() instead"; But that message does not show in my case. Also, I'm not trying to DELETE the page, but TRASH it. I tried using $pages->trash($page) instead of $page->trash() but still I get the same error. This seems like it should be a common behavior...have a Trash button on the edit page for some resource, that posts back to the page and the page is trashed, then redirecting to a different page. The Admin dashboard operates this way to trash pages. What am I missing?
  • Create New...