Jump to content

How to allow system templates for InputfieldSelector for a field?


Recommended Posts

I have a selector field and I need it to be able to select User templates, but User is hidden because it's a system template.

I thought I could make this change with a hook, but I have not been successful. To try, I made a new module (single, auto load) and in its init() method I added code like this:

class MyCustomModule extends Process implements Module {
  ...
  public function init() {
    $this->wire->addHookBefore('Inputfield::getConfigInputfields', function (HookEvent $event) {
      $this->wire->log('getConfigInputfields Fired', ['name' => 'testHooks']);
    });
    $this->wire->addHookBefore('InputfieldSelector::init', function (HookEvent $event) {
      $this->wire->log('InputfieldSelector::init', ['name' => 'testHooks']);
    });
  }
  ...
}

I thought that if I hooked into when an InputfieldSelector got instantiated, I could check whether it was the field I wanted to target and if so, make the setting change. But none of these hooks fired when I edited the page.

Currently, I have achieved this through changing InputfieldSelector.module's __construct()  method, but I wanted to do it with a hook so it has more of a chance of not getting removed on upgrade!

Any help appreciated ?

Link to comment
Share on other sites

Did you set the autoload property in your module?

I've assembled a snippet for site/ready.php that should add a checkbox to InputfieldSelector to allow system templates since the setting itself is already part of the inputfield code. Untested though since I'm in the middle of a big cleanup of my dev environment.

wire()->addHookAfter('InputfieldSelector::getConfigInputfields', function (HookEvent $event) {
  
  $fields = $event->return;
  $inputfield = $event->object;
  
  $f = $event->modules->get('InputfieldCheckbox');
  $f->attr('id+name', 'allowSystemTemplates');
  $f->label = $event->_('Allow system templates');
  $f->setAttribute('checked', $inputfield->getSetting('allowSystemTemplates') ? 'checked' : '');
  $fields->append($f);
  
  $event->return = $fields;
  
});

 

  • Like 1
Link to comment
Share on other sites

  • 2 weeks later...
Posted (edited)

@BitPoet Wow thank you, that worked!

A screenshot of the Field admin page with the new "Allow system templates" checkbox highlighted.

 

I note that:

  • you used ready not init. This makes sense; ready fires after all the installed modules have initialised, and we need ProcessWire to know that the InputfieldSelector module exists before adding a hook, presumably. (Note that your code worked for me using init() instead which I tested to see. I guess this is at risk of a race condition though; if my module loaded before InputfieldSelector did, it might not work).
  • You hooked InputfieldSelector not the parent Inputfield yours worked, mine didn't, so I guess we're not allowed to hook on parent classes?
  • This is a great example of how flexible ProcessWire is. And how much I've yet to learn!

Very grateful for your time responding to this and sorry I didn't see it sooner (note to self: check my notification settings!).

 

 

Edited by artfulrobot
Link to comment
Share on other sites

34 minutes ago, artfulrobot said:

you used ready not init. This makes sense; ready fires after all the installed modules have initialised, and we need ProcessWire to know that the InputfieldSelector module exists before adding a hook, presumably. (Note that your code worked for me using init() instead which I tested to see. I guess this is at risk of a race condition though; if my module loaded before InputfieldSelector did, it might not work).

That shouldn't be a problem, actually. The WireHook class (someone correct me if I'm wrong) just builds a Selector and stores that in its hooks array. Every time a hookable method is called (through PHP's magic __call method), WireHook::runHooks is executed and checks wheter the any of the stored selectors match the currently called class and method and execute those. So it shouldn't matter when exactly you add the hook as long as PW's core has been loaded. For me, it's just a question of keeping the system startup lean why I perfer to add hooks in ready instead of init unless they have to be executed before ready() is triggered.

38 minutes ago, artfulrobot said:

You hooked InputfieldSelector not the parent Inputfield yours worked, mine didn't, so I guess we're not allowed to hook on parent classes?

In theory, it shouldn't matter, but I haven't delved too deeply into the issue.

  • Like 1
Link to comment
Share on other sites

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 account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...