Jump to content

Basics of hooking


VeiJari
 Share

Recommended Posts

Hello forum! 

I started to write my first hook for Processwire but I'm pretty confused how you should write these. My idea is to hook after publishing in init.php (called before templates)  for a certain template. 

 

Here's the code: 

image.png.696daf301396a34832a7d6a24495b693.png

Trying to reset the checkbox (ajasta) and then saving it so it shows unchecked in the admin page when publishing "article" page. 

But the code isn't doing anything. Not even dumping anything

What seems to be the problem? And have you made a similar hook for this usage or am I doing it totally wrong? ?

Thanks for the support in advance!

Link to comment
Share on other sites

Hi @VeiJari

It's usual practice, but not compulsory, to put hooks into /site/ready.php. site/ready.php loads before _init.php.

You're changing the saved page data so you may need to turn off outputting formatting first if saving the entire page, or simply set-and-save the 'ajasta' field, eg (untested):

wire()->addHookAfter('Pages::published', function($event) {
    $page = $event->arguments('page');

    $t = wire()->templates->get($page->template);
    if($t->name == 'artikkeli' && $t->hasField("ajasta") {
        $page->setAndSave('ajasta', 0);
    }   
    $event->return = $page;
});

 

  • Like 4
Link to comment
Share on other sites

I guess $pages is not "ready" in _init.php, since _init.php is loaded pretty early. When PW is up and running and before the template is executed, it runs site/ready.php. So placing hooks in ready.php is the recommended practice.

28 minutes ago, psy said:

site/ready.php loads before _init.php

sorry, no.

  • Like 1
Link to comment
Share on other sites

I'd support the /site/ready.php solution as well. It seems to be the better place for hooks that don't end in a module.

But there is another thing.

Your hooks is tied to the published state or the action of publishing it. While testing this you have to unplublish the page first to test your hook.
Had this testing issue a while back, too. ?

 

  • Like 1
Link to comment
Share on other sites

Sure, init.php runs before ready.php as well, but thanks for the link, which explains this more precisely:

Quote

/site/init.php
This file is included during ProcessWire's boot initialization, immediately after autoload modules have been loaded and had their init() methods called. Anything you do in here will behave the same as an init() method on a module. When this file is called, the current $page has not yet been determined. This is an excellent place to attach hooks that don't need to know anything about the current page.

 

  • Like 3
Link to comment
Share on other sites

On 4/11/2019 at 3:27 PM, psy said:

Hi @VeiJari

It's usual practice, but not compulsory, to put hooks into /site/ready.php. site/ready.php loads before _init.php.

You're changing the saved page data so you may need to turn off outputting formatting first if saving the entire page, or simply set-and-save the 'ajasta' field, eg (untested):


wire()->addHookAfter('Pages::published', function($event) {
    $page = $event->arguments('page');

    $t = wire()->templates->get($page->template);
    if($t->name == 'artikkeli' && $t->hasField("ajasta") {
        $page->setAndSave('ajasta', 0);
    }   
    $event->return = $page;
});

 

Tested and the code works!

Thank you for this.

Our customer also wants the field to be disabled when the page is published, how do you achieve this? 

Quick browsing of the API, there doesn't seem to be a disable() function for a field.

Link to comment
Share on other sites

On 4/11/2019 at 4:02 PM, wbmnfktr said:

Be careful here @Autofahrn and @psy.

@VeiJari is talking about init.php and not _init.php.

  1. init.php
  2. ready.php
  3. finished.php

Just to keep this in mind.

https://processwire.com/blog/posts/processwire-2.6.7-core-updates-and-more/

I was actually talking about /site/templates/_init.php, but after reading the difference of /site/init.php and /site/templates/_init.php, I decided to include psys' solution to site/init.php.

Thank you for this!

  • Like 1
Link to comment
Share on other sites

3 minutes ago, VeiJari said:

Our customer also wants the field to be disabled when the page is published, how do you achieve this? 

Quick browsing of the API, there doesn't seem to be a disable() function for a field.

I have never used it but you could try to hook into the fields visibility via API in some way.

https://processwire.com/docs/fields/dependencies/

 

Link to comment
Share on other sites

$wire->addHookAfter('ProcessPageEdit::buildForm', function($event) {
  $page = $event->object->getPage();
  if($page->template != 'home') return; // example
  if($page->isUnpublished()) return;
  $form = $event->arguments(0);
  $field = $form->getChildByName('title'); // example
  $field->collapsed = Inputfield::collapsedNoLocked;
});

? 

  • Like 5
Link to comment
Share on other sites

58 minutes ago, bernhard said:

$wire->addHookAfter('ProcessPageEdit::buildForm', function($event) {
  $page = $event->object->getPage();
  if($page->template != 'home') return; // example
  if($page->isUnpublished()) return;
  $form = $event->arguments(0);
  $field = $form->getChildByName('title'); // example
  $field->collapsed = Inputfield::collapsedNoLocked;
});

? 

Works like a charm! 

Thank you for this!

And also, I want to thank every one for motivating me to write hooks and seeing how practical and easy they're to make! ?

  • Like 5
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

×
×
  • Create New...