Jump to content


  • Posts

  • Joined

  • Last visited

  • Days Won


Everything posted by Pete

  1. Thanks Bernhard - I had to remove the Save button when adding a new page with a particular template today for a specific reason, so here was my solution which I arrived at thanks to your code above: $this->addHookAfter("ProcessPageEdit::buildForm", function($event) { $page_id = (int)$this->input->get->id; $page = $this->pages->get($page_id); if ($page->template->name == 'my_template_which_only_needs_publish_but_not_save') { $form = $event->arguments(0); // We want to check the publish button is actually visible first - usually there is "isNew=1" at the end of the URL but that can be removed // manually so best to use a more thorough check $publish_button = $form->getChildByName('submit_publish'); if ($publish_button) { $save_button = $form->getChildByName('submit_save'); $form->remove($save_button); } } } }); This will of course revert to just showing the Save button once the page has been saved. Hope that helps someone in future (probably me in about 6 months time when I forget all about it - that's usually the case πŸ˜„ ).
  2. Ha just had another case today where I needed this and forgot I'd already worked it out once nearly a year ago πŸ™„ This happens to everyone right? πŸ˜…
  3. @zoeck Thanks for pointing that out I think it's all fixed now. Curious as I was very sure I'd enabled page numbers already. This blog was a conversion from a Wordpress website to ProcessWire where the aim was simply to keep exactly the same theme and migrate the content. Rather than use the existing files and unpick it from Wordress, I opted to rebuild using Tailwind CSS which I've become addicted to lately and it's always a pleasure as you can pretty much just take a design and get going only occasionally needing to come up with custom styles in your stylesheet. Some tips that you may find useful: 1. preg_replace your content to add native loading="lazy" to all images: preg_replace('/<img((.(?!loading=))*)\/?>/i', '<img loading="lazy"$1>', $content); 2. A tailwind shade generator: https://www.tailwindshades.com/ for example enter #ff9900 then click the colour and you can see all the shades, but more importantly copy and paste them into your Tailwind config file to have them available in your code: for example I can then use: <p class="text-orange-peel-800">My orange appears to have gone rotten</p> πŸ™‚
  4. Thanks @adrian something odd going on with caching assets there so I've turned it off for now 😬 It was working 10 hours ago but will probably be something simple.
  5. I noticed in TinyMCE it's also possible to have predefined HTML templates for snippets of markup which sounds neat. I can't think of any obvious uses right now and HannaCode is likely more powerful for this, but it does make me wonder if there's a way of combining it with HannaCode so that inserting a HannaCode could also show you what the markup would look like: https://www.tiny.cloud/docs/tinymce/6/template/ πŸ€” From what I can see it only inserts parsed HTML so without a way of wrapping it in some sort of ID/data attribute that could be problematic.
  6. I'd 100% love to see the snapshots feature make a comeback eventually - clients can do... "funny" things sometimes (and I've been guilty of it too ?), though I appreciate it's a hard one to crack.
  7. Hi Adrian, it's been a while since I needed this functionality and didn't realise I'd left my own module still up - I'll likely take it down soon and direct people to yours if you think that makes sense? I'm going to use yours for a project, but can I suggest an option to hide the login form? For normal maintenance I wouldn't let any roles log in and as superuser I'd just go to the right URL instead is my thinking. It may also be worth changing the title of your module in the directory to "Protected/Development/Maintenance Mode" so those keywords are found during search as currently only mine comes up for "maintenance".
  8. @bernhard I can't quite work out what the code would look like there, because if I bd() the inputfields on the page, it only shows the "outer" combo field name, not the subfields. Something else to note using my code is that if you output the field DATA (not the inputfield markup) on the frontend (which in my case is a country) using code like this: echo $user->billing_details->country; it won't show the data as it doesn't know what the key/value pairs are supposed to be when formatting the data. So I got around that by doing: echo $user->getUnformatted('billing_details')->country; Which simply outputs whatever you had stored in the DB. I'm sure there's some way of covering all this in 2 hooks or less using your method bernhard but not sure what it would look like for a combo field. For now my 2 hooks and outputting the unformatted value gets me where I need to be. I just wish I'd remembered about getUnformatted 90 minutes ago ?
  9. Ah thanks @bernhard that does make sense, I'll check it out!
  10. I encountered an odd error today and I cannot for the life of me work out what caused it: However I added !is_null($fieldObject) before the count on the line in question (and the other 2 places that same piece of code crops up) and that sorted it. For whatever reason the field object was null. EDIT: Ah - I think this is a PHP8 thing actually which explains why it was working last week and not this week - that's probably it ?
  11. If anyone's wondering how to get the data to save, you need to set the options again prior to processing the input. So here's my example - first hook adds my options to the field so they render, second hook makes the options available when processing the input: wire->addHookBefore('InputfieldSelect::render', function($event) { if($event->object->name == 'my_select_field_name') { $countries = [1 => 'UK', 2 => 'USA', 3 => 'Etc etc']; $event->object->setOptions($countries); } }); $wire->addHookBefore('InputfieldSelect::processInput', function(HookEvent $event) { // Get the object the event occurred on, if needed $InputfieldSelect = $event->object; if ($InputfieldSelect->name == 'my_select_field_name') { $countries = [1 => 'UK', 2 => 'USA', 3 => 'Etc etc']; $event->object->setOptions($countries); } }); Using this in a complicated project where I've got custom tables for some data and it works nicely. Possibly also worth noting this works for checkboxes and radios I think as they are all extended from InputfieldSelect
  12. Thank you - I had Covid last week so haven't had time to look at this yet but looking forward to testing it out this week.
  13. This module is great - thank you. I'd love to see the addition you mentioned above though as there are some forms where I only want to display hCaptcha to guest users since logged-in users on the site I'm working on are already validated by this point. I guess the permission should just hide/not render the form and skip it during form validation but not sure how easy that is. I guess the way to do that in the meantime would be via hooks, so using your example below from the docs, but only target visitors who aren't logged in and render it for just those visitors: <?php // site/init.php wire()->addHookAfter('ProcessPageEdit::buildForm', function (HookEvent $event) { $form = $event->return; $submitButton = $form->getChildByName('submit_save'); if ($submitButton) { $hCaptcha = $event->wire('modules')->get('InputfieldHCaptcha'); $hCaptcha->set('label', __('Spam Protection')); // ... configuration goes here $form->insertBefore($hCaptcha, $submitButton); } $event->return = $form; }); I'll give that a go and see how I go.
  14. Oh nice - wish I'd looked harder before doing it my own way as that sounds ideal ?
  15. I've also been using this great module on another WP conversion project to do the same thing: https://processwire.com/modules/custom-paths/ I'm not 100% sure if it checks for uniqueness (probably) but since everything's being imported by a script I wrote I know they are unique for now.
  16. Haha just got caught out by it again 3 months later and end up here only to find my own comment on it ?
  17. I've got a scenario where I use ProcessWire as a CRM for a client and they have several companies using this now, so it's important to be able to update things easily across all installations. A tricky one recently was working out how to manage translations via API to avoid going into several installations, enabling language support and translating the file manually (in this case they wanted to tweak a message in LRP's confirmation routine). On your master installation, do your translation as normal Export to CSV Upload the CSV file somewhere where your updater code can reference it - I created a folder in site/assets called "uploads" for some CRM-specific stuff, so I added another folder under there for ' Use code similar to the below in your updater script on other installations to first create the JSON file to be translated (it may not already exist) and then import your CSV file and tidy up afterwards - something like the below: <?php $this->modules->refresh(); // I've found this helps first, mostly for modules that have just been pushed to the Git repo but doesn't hurt to do it every time $this->modules->install('LanguageSupport'); // This wasn't yet installed $languages = $this->wire()->languages; $default = $languages->get('default'); // We only use the default language as it's only for the UK market $default->of(false); // It will complain without outputformatting switched off under some scenarios $translator = new LanguageTranslator($default); $translator->addFileToTranslate('site/modules/LoginRegisterPro/LoginRegisterProConfirm.php'); // This generates the JSON file that you would see in PW on the translations page $languages->importTranslationsFile($default, $this->config->paths->assets . 'uploads/imports/default-site.csv'); // This imports the CSV we exported from our master installation unlink($this->config->paths->assets . 'uploads/imports/default-site.csv'); // And we don't need the file afterwards I appreciate it's not a particularly in-depth tutorial, but may help someone out there with a similar need. Our CRM installations are all on an Amazon EC2 instance under separate subdomains, so separate databases too and there's a shell script I use to iterate all the installation folders, get the latest updates from the Github repo and then run an updater script that will do more complex updates like the above code or perhaps alter tables etc. This may get trickier in future if we shift to using something like Docker, or that may make life easier, but at the moment this is all nicely manageable the way it is.
  18. Go for it - just be aware that you don't have the originals afterwards of course. You've reminded me I also have a Craft site I can run this on, although the client does usually manually resize their own images it would be good to check.
  19. It turned 25GB into 11GB by the way. There's still a lot of photos in there ?
  20. One other thing - I am also keeping a copy of the original uploads folder just in case. I've set max resolutions in various CMS' since 2001 and in later years you wonder why you ever set it as low as 800x800 for example ? This way I have the originals if I ever need them again, but I think for the content in question, 1600px max width/height should be absolutely fine. There will also likely be a write-up for this project - it's going to be a while longer though before it's ready.
  21. Hey folks, so in a project I'm working on there are 750+ news articles in WP that are image-heavy in recent years. WP has a habit of storing the original images full-size - well, ProcessWire does too but I always set max dimensions on the image fields to resize during upload to prevent 2mb+ images on my disk. This had resulted in an uploads folder some 25GB in size from 2003-2022. Disk space is, fortunately, cheap nowadays, however I soon realized after mulling it over with Ryan that the easiest and most sane option for importing all those articles was to scrape in the post content HTML into a PW CKEditor field (thanks SimpleHTMLDOM for making this so simple!) but leave the images alone - WP had already done resizes for various lightboxes and galleries so it was just the original, huge images I had to contend with. The solution - on my own copy of the WP uploads dir - was to run this command and watch it go: find ./ -type f \( -iname \*.jpg -o -iname \*.jpeg -o -iname \*.png \) -exec mogrify -quality 90 -verbose -resize 1600x1600\> {} \; It's basically searching all files and subfolders for .jpg, .jpeg and .png files and resizing to no more than 1600px landscape/portrait whilst preserving aspect ratio (no cropping) and 90% image quality. I chose those sizes as the various links in galleries and lightboxes were loading the original file, not one of the WP resized ones, so now we can be fairly sure that we're loading <500kb of image maximum instead of sometimes 10mb+ (some folks have really nice cameras ? ). I'm sure @horst can probably tell me if that command could be better. I think mogrify is usually for a batch of files for example, whereas the find command is serving them up individually so convert might be more appropriate than mogrify, but this command iterates through the files quickly and only resizes which ones it needs to and is happily chugging away right now so I'm happy with it. One thing to note is that any resizing can be a bit CPU-heavy, so if you have the chance to do this on a local server first or out of "normal" hours for site visitors then that's recommended as the server may slow down for the duration.
  22. It's on a CRON job so not a form, but also it's only happening occasionally, not for every email generated by that function. 100% it's since my new code so it's some weird combination of CRON and something else.
  23. Had a bit of time to look into my issue and it's only started since I changed some code, plus that code is run via a Cron job as the guest user so too many variables to check at the moment, but the fault doesn't seem to be in the system or any module at least so that's good.
  24. Experiencing the same lately, but not with every email sent from the same block of code which is all the more curious as it's the same email, just sometimes it'll send once, sometimes twice. I'm using WireMailSMTP with Postmark but will check it with the WireMailPostmark module when I get a chance to see if it's something in WireMailSMTP (unlikely I'm sure, just ruling things out).
  • Create New...