Jump to content


  • Posts

  • Joined

  • Last visited

Everything posted by Andi

  1. As much as I appreciate @bernhard's faith in my motivation (😄), and as much as I'd like to contribute, that would at this point go way above my head.. I keep pushing the day where I'll finally take a dive and learn to use git/hub/lab. And I'm still struggling to find my way around these "new" development tools and procedures.. Lots of ground to cover there currently. But yeah this seems like something that would be really useful. Maybe even as some kind of default way of dealing with user input, as I currently could only think of fringe cases where someone would not want to have this enabled..
  2. After some more testing I feel like this should be safe to implement on the production site.. The only remaining issue at this point being.. The image description input fields seem to be a different kind of beast altogether.. Is there any way to extend the hook to cover these as well?
  3. Ok ... ->count() 🙂 in site/ready.php /** * run all Text and Textarea input fields through UTF-8 normalization * requires justb3a's TextformatterNormalizeUtf8 module * https://modules.processwire.com/modules/textformatter-normalize-utf8/ * * @var Inputfield $inputfield * @var WireInputData $input * @var Language $language * */ $wire->addHookBefore('InputfieldTextarea::processInput, InputfieldText::processInput', function (HookEvent $event) { $inputfield = $event->object; $input = $event->arguments(0); if (wire()->modules->isInstalled("TextformatterNormalizeUtf8")) { if ($this->languages && $this->languages->count() > 1) { foreach ($this->languages as $language) { $input_var_name = $language->isDefault() ? $inputfield->name : "{$inputfield->name}__{$language->id}"; $normalize_input = $input->$input_var_name; wire()->modules->get('TextformatterNormalizeUtf8')->format($normalize_input); $input->set($input_var_name, $normalize_input); } } else { $input_var_name = $inputfield->name; $normalize_input = $input->$input_var_name; wire()->modules->get('TextformatterNormalizeUtf8')->format($normalize_input); $input->set($input_var_name, $normalize_input); } } $event->arguments(0, $input); }); This is by no means thoroughly tested.. Use at your own risk 😉 Does anyone see how there could be any downsides to this approach on a live PW site?
  4. So on the input side of things.. I'm thinking, since we don't know about ..but we have @justb3a's module we could combine @interrobang's idea of hooking into InputfieldTextarea::processInput with calling the textformatter module to sort out normalization right off the bat.. This almost works 😉 $wire->addHookBefore('InputfieldTextarea::processInput, InputfieldText::processInput', function (HookEvent $event) { /** @var Inputfield $inputfield */ /** @var WireInputData $input */ /** @var Language $language */ $inputfield = $event->object; $input = $event->arguments(0); if (wire()->modules->isInstalled("TextformatterNormalizeUtf8")) { bd($this->languages); // ### this doesn't seem to be an array ### if ($this->languages && $this->languages->count > 1) { // ### this part never gets called ### foreach ($this->languages as $language) { bd("language loop"); $input_var_name = $language->isDefault() ? $inputfield->name : "{$inputfield->name}__{$language->id}"; $normalize_input = $input->$input_var_name; wire()->modules->get('TextformatterNormalizeUtf8')->format($normalize_input); bd("$input_var_name :: $normalize_input"); $input->set($input_var_name, $normalize_input); } } else { // ### this part works ### $input_var_name = $inputfield->name; $normalize_input = $input->$input_var_name; wire()->modules->get('TextformatterNormalizeUtf8')->format($normalize_input); $input->set($input_var_name, $normalize_input); bd("$input_var_name :: $normalize_input"); } } $event->arguments(0, $input); }); With this, utf-8 normalizing works for the default language input fields, but currently all others remain untouched. I tried looking around for a working example of how to get to the language fields, but no luck so far.. Also feeling just a tad bit twitchy about hooking in at such a deep level, but so far no problems during testing.. Does anyone have an idea where I'm going wrong here? Thanks and all the best..! Almost there I think 😄
  5. Haha @bernhard easy on me.. Still coding like it's 2005 over here.. Guess the 10 year break made me miss out on a whole lot of stuff 😉 Good lord I'm glad these arrays are no longer needed 😄 if ($modules->isInstalled("TextformatterNormalizeUtf8")) { $pgs = $pages->find("template=artist"); foreach($pgs as $p) { $p->of(false); $summary=$p->summary; bd("OLD: $summary"); $this->modules->get('TextformatterNormalizeUtf8')->format($summary); bd("NORMALIZED: $summary"); $p->summary = $summary; $p->save('summary'); } }
  6. Just getting started here but I can already confirm that @justb3a's module completely fixes this issue on the frontend side of things.. Now I'd basically just need to find a simple way to run every text & textarea field in both language versions through the normalizer.. Actually also pagetitle fields.. Or ideally, literally every bit of text that's being saved to the database.. Or would there be any downsides to that at all? --- Module works fine on PW v3.0.148 by the way
  7. I'm aware of that, but thanks for pointing it out @interrobang Thought I just put that here for future reference, I'm imagining many people (like me until 3 hrs ago 🙂) haven't even heard of the term utf normalization. That thread at the wordpress tracker is a great read btw. There's a lot there already, so I think we should be able to get this whole thing sorted out by tomorrow night. Cheers & danke vielmals 😉
  8. Always helps to know what you're looking for 🙂 https://modules.processwire.com/modules/textformatter-normalize-utf8/ Thanks for the pointers @interrobang, this is going to help a lot..
  9. Haha ok looks like you're right on the money 🙂 Awesome stuff, that really makes this all seem a little less nonsensical.. I'll absolutely make sure of that.. Will set this up tomorrow first thing in the morning and report back. Thank you all for your help and advice! Schönen Feierabend! 😉
  10. Hey @interrobang, thanks a bunch. A different angle altogether.. And I guess I'll need to read up on utf normalization a little bit 🙂 https://stackoverflow.com/a/7934397 Guess the problem is that I don't actually, on a technical level, understand what's happening at all.. But that does sound like we're headed in the right direction here.. I'll set up a testbed tomorrow on my localhost and try this approach, since we've already pretty much ironed out all the problematic database records on the dev site. So am I understanding correctly that this hook would also utf-normalize textarea fields for existing records, as long as a user opened the page for editing and just hit save once? Thanks again and greetings from Regensburg 😉
  11. Haha ok then maybe it should also be mentioned that on both of my Linux machines none of this cr#p is any issue at all 🙂
  12. Haven't gotten to the coding part yet, but we had a longer team conference this morning and tried to narrow down this issue a little bit.. In the name of science, so to speak. We tried 4 people with 4 different setups, all copy/pasting to PW from the same PDF file, and those were the results: #1 macOS High Sierra 10.13.6 - Apple PDF Preview -> PW: Broken diacritics - Acrobat Reader -> PW: Broken diacritics - Google Drive (Browser) internal document viewer -> PW : Good diacritics #2 macOS Catalina 10.15.4 - Acrobat Reader -> PW: Good diacritics - Acrobat Reader -> Text Editor -> PW: Broken diacritics (no idea why..) - Google Drive (Browser) internal document viewer -> PW : Good diacritics #3 Windows 10 - No Problems with diacritics during copy/paste #4 Windows 7 - No Problems with diacritics during copy/paste So although I'll still have to implement a hook to deal with the existing records in the database, I think we've established a workflow for #1 to get clean data into the system right off the bat, or at least for the time being.
  13. @bernhard how did I totally overlook that all this time? 🙂 So if I wanted to use this on more than one fieldtype on a multilingual site I'd just need two nested foreach-loops in // Something along these lines? public function replaceBadUmlauts(HookEvent $event) { $page = $event->arguments(0); $bad = array("ü","ö","ä","Ü","Ä","Ö"); $good = array("ü","ö","ä","Ü","Ä","Ö"); $fields = ?? somehow get fields into an array; foreach ( ??fields as $field) { foreach ( ??languages as $language) { $page->??field = str_replace($bad, $good, $page->??field); } } } I'll need to dig into the documentation a little bit and see how to do this.. Thanks for putting me on the track!
  14. Haha thanks @bernhard, you're the man. Think I'm ready to be a PW module coder just yet..? Still a little scared of hooks although it is getting better 🙂 This looks promising, I'll get on it after breakfast 😉
  15. Part III So the questions would of course then be... 1. What the flying f&#k is this sh#t 🙂 2. how would I approach getting all this into a hook (I'm thinking on saveReady maybe?) so this would be fixed automatically for summary & body for both language versions of the page - whenever the user pastes another crazy mess of trematized Umlaut madness into an artists profile? 😄 Thank you all in advance & god bless.. Glad I finally got this off my chest
  16. Part II So one year later we're working a site that features little artist profiles with a summary, body/longer band info, and some pictures. These guys are from all over the place, Spain, France, Germany and all the docs the client is copy/pasting from are PDFs. He's also on a Mac (if that's at all related), and the ü's are back Frontend: Backend: Together with of tons of messed up diacritics in Spanish & French names and so on. Also this time both lower (äöü) and uppercase (ÄÖÜ) have tremas, all of them. So no way we could manually replace all that for currently ~250 artists in both the English and German language versions. We did try pasting the text into a Code Editor first and then copying it over to PW, but that also did nothing.. So the workaround we're currently using is this: This is what the bookmark in Finder looks like that helped me build a selector to get the affected pages. I just copy/pasted the "bad" Umlauts straight from PWs backend fields into the value fields here. And then wrote a makro in Tracy Debugger which currently looks like this // CAREFUL WITH $PAGE IN MAKROS $pgs = $pages->find("summary%=ü|ö|ä"); bd($pgs); bd("Found " . $pgs->count() . " pages"); // try to add something to this array in Tracy or a code editor of your choice and watch all hell break loose $bad = array("ü","ö","ä","Ü","Ä","Ö"); bd($bad); $good = array("ü","ö","ä","Ü","Ä","Ö"); bd($good); foreach($pgs as $p) { $p->of(false); $summary_old=$p->summary; $summary_new = str_replace($bad, $good, $summary_old); bd($summary_new); $p->summary = $summary_new; $p->save('summary'); } Which, on it's face, looks like the most ridiculous piece of code you could ever write. But it works 🙂
  17. So here's a thing I've been chewing on for a while now.. And although I kind of have a handle on it at this point, I'd still love to understand what is actually happening here 🙂 Please bear with me.. Last year I did a project for a client in Lübeck, Germany, and implemented a full text search on $page->body and $page->summary not too different from @ryan's default site frontend search functionality. Got it all to work nicely without too much hassle, client was already filling up the site with content, and then one day I decided to test the frontend search by looking for pages with "Lübeck" in them. Which threw out 3 matches in more than 50 pages. Naturally, with the site being in Lübeck, that number seemed a little off, so I checked manually and realized there were lots of pages missing from the results. So I thought ok something's broken about my search. Half a day of testing later, and ending up using Firefox's Ctrl+F search with "Match Diacritics" + "Highlight All" on the frontend, i realized that not all ü's were the same across the site. Some would get highlighted (those that PW's search would pick up), and some wouldn't. // try to CTRL+F this page and search for one of these ü != ü Talking to the client it turned out that he had copy-pasted large chunks of the content from PDF files. He was working on a Mac, so I did some research and found a bunch of information on all sorts of weird diacritics problems when doing exactly that 😕 These are in german but I think the basic idea should come across https://blog.k-webs.ch/2017-02-verschobene-punkte-ueber-umlauten.html https://www.macuser.de/threads/falsche-umlautdarstellung-ue-punkte-versetzt.748967/ So it turned out some of the buggers were actual ü's, and some were actual u's with a "trema" attached to them. Something a little bit like this // but not quite u¨ Now the part where this gets even more confusing is, on the frontend side they don't look the same across different OS's / browsers / what have you. Chrome on apple seems to handle them completely different from FF on Windows 7 for instance, so the client couldn't even understand what the problem was because he didn't see it. Also please note that during that particular project all other Umlaute / Diacritics were fine, äs, ös, uppercase, lowercase,, everything. Just the little ü's were acting up. So we sat down and started out search & replacing them. There was not a lot of time, aaand well I was new to PW 🙂 ... stay tuned for Part II where we're doing a project with over 200 international artists with all sorts of funky diacritics in bandinfos *all coming from PDF Files* 😄
  18. Set this up for the first time tonight, works really well over here. Just to save someone else some head-scratching, if you do this: Consider adding include=all to your selector to also iterate through unpublished and hidden pages when synchronizing your relationships.. // Get all pages where page_field_a is not empty, including hidden and unpublished pages $pgs = $pages->find("page_field_a.count>0, include=all"); ... Great work on the module @Robin S, coming in very handy 🙂
  19. This is the line https://github.com/netcarver/PW-FieldtypeTime/blob/4332e922d6c8e98b64e8e6e408ad7c71e318ffff/InputfieldTime.module#L83 So for the time being, in InputfieldTime.module change line 83 to something like $attrs['placeholder'] = "00:00";
  20. Awesome module @Mike Rockett, been using this on a couple of sites last year without any hiccups. I have a case here that I'm not sure how to handle right now. Following this post Or this bit more specifically /site/templates/includes/hooks.php /** * This hook modifies the default behavior of the Page::path function (and thereby Page::url) * * The primary purpose is to redefine blog posts to be accessed at a URL off the root level * rather than under /posts/ (where they actually live). * */ wire()->addHookBefore('Page::path', function($event) { $page = $event->object; if($page->template == 'post') { // ensure that pages with template 'post' live off the root rather than '/posts/' $event->replace = true; $event->return = "/$page->name/"; } }); I set up a hook to mask a url segment that I don't want to show up in page paths in a certain section of my site. This is all fine and dandy and working as advertised, but since the hook is living in /site/templates/ and is only affecting the front-end part of the site, the paths that show up in sitemap.xml still show the original url segment ( /posts/ in @ryan 's example) Now ideally I'd rather not mess with PW's page path behaviour in the backend, so I'm wondering if there's a way to somehow make sitemap.xml reflect the hooks from the front-end side of things without too much hacking around? Also new to hooks and trying to be careful around them 😉 All the best and thanks in advance!
  21. Dude you're fast! 🙂 Looking great so far, nice and simple. With this in site/templates/_init.php I can do // retrieve all images that don't have mytag1 $images = $page->images_header->excludeTag('mytag1'); // retrieve all images that don't have mytag2 $images = $page->images_header->excludeTag('mytag2'); // retrieve all images that have neither mytag1 or mytag2 $images = $page->images_header->excludeTag('mytag1|mytag2'); I'll test this further and report back. Awesome stuff @Jan Romero, much appreciated!!
  22. Continuing my journey into PW hooks, I'm trying to find a way to retrieve all images from a page that explicitly *do not* have a certain tag (or tags) attached to them. Found this post from 2015 But I'm wondering if there's a more elegant way to go about this. Let's say I have a multi-image field called "images_header" and instead of $page->images_header->findTag('mytag'); I would like to do this: $page->images_header->excludeTag('mytag'); So I'd be able to do // find images that don't have the tag "mytag" $images = $page->images_header->excludeTag('mytag'); // check if there's any images if (count($images)>0) { // do something.. } Would this be possible by hooking into Pagefiles somehow? There's this bit in /wire/core/Pagefiles.php Line 626 that I'd basically just need to reverse (or at least in my mind 😄 ) public function findTag($tag) { $items = $this->makeNew(); foreach($this as $pagefile) { if($pagefile->hasTag($tag)) $items->add($pagefile); } return $items; } Any ideas on how this could be done in a graceful manner? Thanks in advance!
  23. Hey again, following @bernhard's suggestion of making stuff a little more readable, and after some refactoring, here's the result: In templates/admin.php // user custom theme warning in backend $this->addHookAfter('Process::execute', function($event) { // make stuff more readable $user = $this->wire('user'); // early exit if user is not logged in if(!$user->isLoggedin()) return; // array of themes that will be excluded $x = array('', 'default'); // early exit if current user theme is in excluded array if(in_array($user->custom_theme->value, $x)) return; // set up message $u = $user->name; $t = $user->custom_theme->title; // set up path for profile link $p = $this->wire('config')->urls->admin . "profile"; // send message $this->wire->warning("Frontend wird für Benutzer \"$u\" aktuell mit dem Theme \"$t\" ausgegeben. <small>Einstellung \"Frontend Theme\"im <a href=\"$p\">Benutzer-Profil</a></small>", Notice::allowMarkup); }); Also added an array of values to be excluded to make this more reusable in the future. Looking neat, working as expected. Thanks again and servus from Bavaria!
  24. Thanks @bernhard, it really does 😉 I'm in my 5th or so project with PW but haven't really used hooks so far. Looks like the next best thing to a love affair 🙂 Thank you both again for your help, greatly appreciated!
  25. Works a treat. Thanks for explaining, that was very helpful! Here's the finished hook for future reference. In templates/admin.php // user template switch warning in backend $this->addHookAfter('Process::execute', function($event) { // only works for logged in users that have a custom frontend template enabled if ($this->wire('user')->isLoggedin() && $this->wire('user')->template_switch->value != 'default') { $u = $this->wire('user')->name; $t = $this->wire('user')->template_switch->title; $p = $this->wire('config')->urls->admin . "profile"; $this->wire->warning("Frontend der Seite wird für User $u aktuell mit dem Template \"$t\" ausgegeben. <small>Einstellung \"Frontend Template\"im <a href='$p'>Benutzer-Profil</a></small>", Notice::allowMarkup); } });
  • Create New...