Orkun Posted May 15, 2019 Share Posted May 15, 2019 Hi Guys My Processwire Installation has 4 Languages installed (German, French, Italian and English). German is the default language. How can I change the behavior of a required Multi-Language Field, that it checks if one of the lanuages is filled out (and not how it is like now where it only checks, if the default language is filled out)? Do I need a Hook for this or some js action? Kind Regards Orkun Link to comment Share on other sites More sharing options...
dragan Posted May 16, 2019 Share Posted May 16, 2019 I had to do something similar once. Here's something you might try as a starting point. A hook in site/ready.php : if ($this->page->template == 'admin') { $this->addHookBefore('Pages::saveReady', function(HookEvent $event) { $form = $event->object; $page = $event->arguments(0); $user = wire('user'); if($page->template == "basic-page"){ $summary = $page->summary; $languages = wire('languages'); // see wire/core/InputfieldWrapper.php $item_error = "<p class='InputfieldError ui-state-error'><i class='fa fa-fw fa-flash'></i><span>{out}</span></p>"; $js = "<script>$(\"wrap_Inputfield_summary div.InputfieldContent.uk-form-controls.langTabsContainer\").append(\"$item_error\");</script>"; foreach($languages as $language) { if($language->isDefault()) continue; $user->language = $language; $langName = $language->name; if(strlen($summary)<50) { $form->error("Summary in $langName is too short!"); // regular error message at the top } } } $event->return = str_replace("</body>", "$js</body>", $event->return); // flash error msg on the field }); } (Adjust template and field name of course) This will still let the page save, and only display a red error msg on top, not the actual "required field error". I have no idea how PW does that.. I'd have to dig around in the core files, but no time atm... Of course it would also be nicer if the actual error message would be displayed in the user's language (d'oh)... Link to comment Share on other sites More sharing options...
Orkun Posted May 16, 2019 Author Share Posted May 16, 2019 18 minutes ago, dragan said: I had to do something similar once. Here's something you might try as a starting point. A hook in site/ready.php : if ($this->page->template == 'admin') { $this->addHookBefore('Pages::saveReady', function(HookEvent $event) { $pages = $event->object; $page = $event->arguments(0); $user = wire('user'); if($page->template == "basic-page") { $summary = $page->summary; $languages = wire('languages'); foreach($languages as $language) { if($language->isDefault()) continue; $user->language = $language; $langName = $language->name; if(strlen($summary)<50) { $this->error("Summary in $langName is too short!"); } } } }); } (Adjust template and field name of course) This will still let the page save, and only display a red error msg on top, not the actual "required field error". I have no idea how PW does that.. I'd have to dig around in the core files, but no time atm... Of course it would also be nicer if the actual error message would be displayed in the user's language (d'oh)... Thanks @dragan I had solved this with a hook into the processInput of the corresponding Inputfield. It kinda feels dirty but it does the job. It checks at first if all languages are empty. If all languages are empty, it gets the old values of the page and gives the data to the incoming post request, so that the old values are still in place. And also an error message is returned on the field. $wire->addHookAfter("InputfieldPageTitle::processInput", function(HookEvent $event) { if(wire('user')->hasRole("partner")){ $field = $event->object; $page = $this->modules->ProcessPageEdit->getPage(); $allowedTemplates = array( "event", "partner", ); if(in_array($page->template->name, $allowedTemplates)){ $errorCounter = 0; foreach($this->languages as $lang){ $lname = $lang->isDefault() ? "" : "__".$lang->id; if($this->wire('input')->post("title$lname") == ""){ $errorCounter++; } } // If all multi-language Fields are empty if($errorCounter == 4) { // Needs to be done like this for the default language. Somehow id doesn't work inside the foreach loop underneath $default = $this->languages->getDefault(); $oldvalue = $page->getLanguageValue($default, 'title'); $field->value = $oldvalue; // iterate through all languages except default foreach($this->languages as $lang){ if(!$lang->isDefault()){ // Get value which is already in db / on page $oldvalue = $page->getLanguageValue($lang, 'title'); // Overwrite incoming post with old data from the db $postvar = "title__{$lang->id}"; $this->wire('input')->post->$postvar = $oldvalue; } } // Populate Error to field $field->error("You must fill in at least one language"); } } } }); $wire->addHookAfter("InputfieldTextarea::processInput", function(HookEvent $event) { if(wire('user')->hasRole("partner")){ $field = $event->object; $page = $this->modules->ProcessPageEdit->getPage(); $allowedTemplates = array( "event", "partner", ); $allowedFields = array( "body", "about_us", "why_we_join" ); // If field is already required, abort the hook if($field->required) return; $f = $this->wire('fields')->get($field->name); if(in_array($page->template->name, $allowedTemplates) && in_array($field->name, $allowedFields) && $f instanceof Field && $f->type instanceof FieldtypeLanguageInterface){ // Check if field is empty in all languages $errorCounter = 0; foreach($this->languages as $lang){ $lname = $lang->isDefault() ? "" : "__".$lang->id; if($this->wire('input')->post("{$field->name}$lname") == ""){ $errorCounter++; } } // If all multi-language Fields are empty if($errorCounter == 4) { // Needs to be done like this for the default language. Somehow id doesn't work inside the foreach loop underneath $default = $this->languages->getDefault(); $oldvalue = $page->getLanguageValue($default, $field->name); $field->value = $oldvalue; // iterate through all languages except default foreach($this->languages as $lang){ if(!$lang->isDefault()){ // Get value which is already in db / on page $oldvalue = $page->getLanguageValue($lang, $field->name); // Overwrite incoming post with old data from the db $postvar = "{$field->name}__{$lang->id}"; $this->wire('input')->post->$postvar = $oldvalue; } } // Populate Error to field $field->error("You must fill in at least one language"); } } } }); Kind Regards Orkun 1 Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now