-
Posts
1,306 -
Joined
-
Last visited
-
Days Won
13
Everything posted by Juergen
-
Here are all enhancements for the template select field that I have used: 1) On page add process: Make an empty option at the top (thanks @Robin S for the easier solution) and give the user a note to select a template (optional add an additional class to style the inputfield) 2) On page edit process: Show the template select field inside the content tab instead of the settings tab (thanks @abdus), give the user a note to save the page after template change and optional add an additonal class to style the inputfield. Here are the complete code lines which should be copied into the ready.php. // 1) Template select field enhancements //a) add empty select on top of template and additional note select on page add $wire->addHookAfter('ProcessPageAdd::buildForm', function(HookEvent $event) { $form = $event->return; $template_select = $form->getChildByName('template'); $options = $template_select->getOptions(); $options = array('' => '') + $options; $template_select->set('options', $options); // Set the value to something that will never match an option in the select (any string will do) $template_select->value = 'a'; $template_select->attr('required', 1); $template_select->notes = __("Please select which type of page you want to create first."); //$template_select->addClass('importantfield', 'wrapClass'); //optional }); //b) Add class and additional note to template select field on page edit $wire->addHookBefore('InputfieldSelect::render', function(HookEvent $event) { if($this->process != 'ProcessPageEdit') return; $page = $this->process->getPage(); $inputfield = $event->object; if($inputfield->name === 'template') { $inputfield->notes = __("If you want to change the template, then choose your desired template and press the save button before filling out the fields."); //$inputfield->addClass('importantfield', 'wrapClass'); //optional } }); //c) move template select to content tab on page edit wire()->addHookAfter('ProcessPageEdit::buildForm', function ($event) { // make sure we're editing a page and not a user if ($event->process != 'ProcessPageEdit') return; $page = $event->object->getPage(); // does page template start with event_? if (strpos($page->template, 'event_') !== 0) return; $form = $event->return; $contentTab = $form->children->get('id=ProcessPageEditContent'); $settingsTab = $form->children->get('id=ProcessPageEditSettings'); if (!$settingsTab) return; $template = $settingsTab->get('template'); if (!$template) return; $settingsTab->remove('template'); $contentTab->prepend($template); }); Here are some screenshots: a) Page add As you can see the wrapper of the inputfield is grey in this case - this is because I have added a custom class to mark this field as important (background: #ddd). b) Page edit Maybe this could be useful for others too, so feel free to try it out if you want.
-
In my case I have a parent template for events. Under this parent the editor can create events and he can choose between 4 different type of events (at the moment). Each of them has its own template and form with different fields. Therefore it is necessary in this case that editors can choose between these types (depending on which type of event should be added). Fe if the editor wants to add a new event with price, max. participants, deadline for reservation and so on.. he needs other input fields than if he wants to add only a date for a company vacation. It would be great if this could be part of the core (fe with the option to select in the settings if a "Please select" should be displayed or not).
-
This is my last an best working approach with no JS (only PHP). In this case I use a Hook with a regex and a session variable to add an additional option tag with "Please select" at the top. So the user has to select one of the template types. Otherwise he will get an error message. Only to mention: There is also another Hook used to create the notice at the bottom (but this is not part of this topic ) Here is the code, which should be placed inside ready.php: $wire->addHookAfter('InputfieldSelect::render', function(HookEvent $event) { if($this->process != 'ProcessPageAdd') return; $inputfield = $event->object; if($inputfield->name === 'template') { $regex = '#<\s*?select\b[^>]*>(.*?)</select\b[^>]*>#s';//regex to get all content (options) between the select tags $str = $event->return; preg_match($regex, $str, $match); $origoptions = $match[1];//get all original options $options = $origoptions; if(isset($_POST['template'])) wire('session')->selectedoption = wire('input')->post('template');//set session after POST if(wire('session')->selectedoption){ wire('session')->remove('selectedoption');//remove session } else { $options = str_replace("selected='selected'", '', $origoptions); //remove selected attribute on first load } $newoptions = '<option value="">'.__("Please select").'</option>'.$options;//create all options including the empty option tag at the beginning $result = str_replace($origoptions, $newoptions, $str);//replace the original options with the new options $event->return = $result; } }); Short explanation: The regex is used to get all options between the select tags (needed a little bit later to add the additional option tag on the top) The session is used to check if the page is loaded for the first time. If yes (no session created) than the pre-selected option will be removed, so that the "Please select" option will be selected on the first page load. The session will be removed afterwards. So this step is only necessary to get the "Please select" as pre-selected value on the first page load. Afterwards the additional option tag with "Please select" will be added to the original option tag which was grabbed with the regex. The final step is to output the modified select. At the moment I didnt find any problems or errors with this code, but if someone has some improvements please let me know. Best regards
-
Thank you @Robin S, your solution works!!! Also thank you for your detailed explanation, but where do you get all your knowledge about Hooks ? A big thanks to all other contributors for your help!
-
Thank you @kixe I will try this tomorrow.
-
I have put the code inside the ready.php, but I need to run it only on certain templates and under certain conditions. Therefore I need the page to get the template associated with it. So I dont want to disable them permanently only if the page has no children. If childrens were created the field should be enabled. The idea is to make this field (a checkbox field) checked and disabled if there are no children created. If the user has created at least 1 child page, then this checkbox field will be unchecked and enabled. The automatic checking works with this Hook after a new page (with no children) is added //Set create events to true if there are no child pages $this->pages->addHookAfter('added', function($event) { $page = $event->arguments('page'); $field = $event->arguments('field'); if(in_array($page->template->name, array('event_businessvacations','event_specialbusinesshours','event_dates','event_events'))) { if(count($page->children) == 0){ $page->setAndSave('createevents', true); } } }); To prevent the user to uncheck the checkbox I want to disable it in this case.
-
Both possible solutions dont work $page = $event->object->hasPage; or $pages->addHookBefore('Inputfield::render', function($event) instead of $this->pages->addHookBefore('Inputfield::render', function($event) $page is always empty
-
Hello, I have written a hook to disable an inputfield on certain conditions: //Disable createevents field if there are no children $this->pages->addHookBefore('Inputfield::render', function($event) { $page = $event->arguments(0); $field = $event->object; if(in_array($page->template->name, array('event_businessvacations','event_specialbusinesshours','event_dates','event_events'))) { if(count($page->children) == 0){ if('createevents' === $field->name ){ $field->attr("disabled" , "disabled"); } } } }); I am getting always following notice from Tracy: PHP Notice: Trying to get property of non-object in /home/.sites/24/site1275/web/site/ready.php:310 This is the line where $page is defined. How can I grab $page in this case correctly or do I have to use another type of Hook?
-
Ideas and best practices to secure a member registration system
Juergen replied to modifiedcontent's topic in Security
Hello @modifiedcontent Composer safes you a lot of time on updating and installing PHP-libraries which you want to use in your project. I use more than 1 external PHP library on my projects, so it makes really sense in my case. Honeypot class is only one of them. If you have time you could read how to install it on your system. It seems to be difficult at the beginning, but there are also tutorial videos on Youtube that are really good and easy to follow. The only thing to mention: you have to work with the CLI (command line interface). If you want to install for example the Honeypot class you only have to write composer require dominiquevienne/honeypot into your CLI and if you want to update it later you only have to write composer update Thats all and the latest version will be installed. No need to look for updates manually. No need to install updates manually. So its a really useful solution to install libraries and keep them up to date with less work.- 10 replies
-
- 1
-
- no subscription detected
- not recognized
-
(and 4 more)
Tagged with:
-
How to store translateable value in multilanguage textfield via API
Juergen replied to Juergen's topic in General Support
Thanks for your tipps. I will try it via the Hook method. -
How to store translateable value in multilanguage textfield via API
Juergen replied to Juergen's topic in General Support
Thanks @BitPoet, the reason for this is because I want to show additional event info inside the page tree next to each event. So if the event has a specific start and end time, the times will be shown next to the date. If the event is all day long, the text "all day long" (in German ganztägig) will be displayed. Therefore I have created a simple textfield (name: eventpagetree) in which the corresponding value will be added via a Hook. On the template side I create the pagetree values like this: That was the idea behind this. -
Hello @ all, I am struggeling by storing a translateable string into multilanguage textfield via the API. This is the translateable string: __("all day long") I want to store this into the multilanguage textfield, but it doesnt work as expected. This is what I have so far: foreach ($this->languages as $lang) { $langtype = $lang->get('name'); $page->eventpagetree->setLanguageValue($langtype, __("all day long")); } But this stores always the same value in both languages. The name of the multilanguage textfield is "eventpagetree" in this case. Can someone give me a hint or a working solution?
-
Yeah, now I see it!
-
Thanks for your efforts. No need to hassle!
-
I have sent you a PM.
-
Ok I have commented it out if (!$dir->isDir() /*&& strpos($path, '/.')*/ === false && preg_match($fileNamePattern, $path) && !in_array(basename($path), $excludeFilenames) ) { but no effect
-
Ok clearing the cache doesnt have any impact on the behaviour.
-
-
I have a lot of hooks inside ready.php, which will be loaded with every page load - so there are a lot of
-
Other toggles from other panels work as expeceted. I am running Tracy in Backend at the moment, so no conflict with frontend scripts. Only to mention: My Antivir software from Kaspersky adds a JS-File inside the head section of the page. Maybe this could be a reason.
-
I am using the latest Firefox but I have also tested it with IE - same result. Browser console doesnt show any errors.
-
Another question: in the panel there is the button "toggle all", but nothing happens if i click on it.
-
Ok, i figured it out. Adding $paths = array(); before the foreach start solves the problem. So it seems that if $path is not defined as an array before the foreach, it doesnt work. So the complete code is like this: $paths = array();//this solves the problem foreach ($iter as $path => $dir) { // '/.' check is for site module backups - SKIP_DOTS above is not excluding these if (!$dir->isDir() && strpos($path, '/.') === false && preg_match($fileNamePattern, $path) && !in_array(basename($path), $excludeFilenames) ) { $paths[] = $path; } } return $paths; Best regards