Jump to content

Recommended Posts

Posted

While this is working perfectly:

public function init() {
    $this->addHookAfter('Page::render', $this, 'replaceEverything');
} 

This is not, nothing happens:

public function init() {
    $this->addHookBefore('Page::render', $this, 'replaceEverything');
} 

replaceEverything looks simply like this:

public function replaceEverything($event) {
    $event->return = "REPLACED, YO!";
} 


I want to replace the rendering entirely, so a hook after would not be efficient, since I don't need the previous rendering.

What's wrong?

  • Like 1
Posted

$event->replace=true;

You mean like this?

public function replaceEverything($event) {
    $event->replace = true;         
    $event->return = "REPLACED, YO!"; 
} 

That did nothing =(

Posted

Thanks WillyC ... still not working ...

This is my method:

public function replaceEverything($event) {
    $event->replace = true;         
    $event->return = "REPLACED, YO!"; 
} 

it still does not do anything when using (the page gets rendered as usual):

public function init() {
	$this->addHookBefore('Page::render', $this, 'replaceEverything'); 
}

But it works, so it replaces when using:

public function init() {
	$this->addHookAfter('Page::render', $this, 'replaceEverything'); 
}

=(

Posted

If you hook before render, there's no $event->return (yet). So you can't replace anything, only if you echo out your stuff and exit() it will work. This has been like this ever since, and I know because I played with it, but never actually needed it or seen any use for it.

  • Like 2
Posted

Thanks Soma, the echo and exit method might be sufficient for my case. Have to look into it further.

Still, I am wondering why the $event->return is not working here. I would consider this a bug, since it's documented here:

http://processwire.com/api/hooks/ (scroll to "How can my hook read (or modify) the return value of the hooked method?")

that you can influence the returned value of hookable methods this way, with no stated exception.

Posted

This Page::render is kind of a special case, because there isn't actually a Page::render() method if you look in the Page class. It is itself a hook added by the PageRender.module. So you can't replace it since the method doesn't actually exist. Instead, you'd have to hook the source of that Page::render hook, which is actually: PageRender::renderPage

  • Like 2
Posted

In your case, if your before hook replaces PageRender::renderPage, you should be able to just echo your output directly. You don't need to exit or stop execution. Meanwhile, I will look into making $event->return; work for before hooks with $event->replace = true; 

Posted
Meanwhile, I will look into making $event->return; work for before hooks with $event->replace = true; 

I figured it out. Since PageRender::renderPage is providing the rendered output in $event->return; rather than the function returning it (since it is actually a hook to a non-existent Page::render), then you have to do the same. As a result, this code in your before hook function should work:

$otherEvent = $event->arguments(0); // grab event provided to PageRender::renderPage
$otherEvent->return = "<p>Hello World</p>"; // plug in our value
$event->replace = true; // prevent PageRender::renderPage from being called
  • Like 3
  • 8 years later...
Posted
On 8/6/2013 at 6:21 PM, ryan said:

I figured it out. Since PageRender::renderPage is providing the rendered output in $event->return; rather than the function returning it (since it is actually a hook to a non-existent Page::render), then you have to do the same. As a result, this code in your before hook function should work:

$otherEvent = $event->arguments(0); // grab event provided to PageRender::renderPage
$otherEvent->return = "<p>Hello World</p>"; // plug in our value
$event->replace = true; // prevent PageRender::renderPage from being called

Hi @ryan, is it something that is still relevant ?

I'm trying to use this for a module I'm writing but it doesn't seem to work as the after hook is still executed, even with `replace` set to true. Here's a boiled down sample of my setup:

public function init() {
	$this->addHookBefore("PageRender::renderPage", $this, "beforeRenderPage");
	$this->addHookAfter("PageRender::renderPage", $this, "afterRenderPage");
}

protected function beforeRenderPage($event) {
	$parentEvent = $event->arguments(0);
	$page        = $parentEvent->object;
	$markup      = $this->wire()->cache->getFor($this, "cache-$page->id");
	if($markup) {
		$parentEvent->return = $markup;
		$event->replace = true;
	}
}

protected function afterRenderPage($event) {
	$parentEvent = $event->arguments(0);
	$page        = $parentEvent->object;
	$this->wire()->cache->saveFor($this, "cache-$page->id", $parentEvent->return);
}

Thank you in advance for your help.

Posted
9 hours ago, monollonom said:

I'm trying to use this for a module I'm writing but it doesn't seem to work as the after hook is still executed, even with `replace` set to true.

I don't think $event->replace = true is supposed to have any effect on whether an "after" hook fires for a method - it just means that the code inside the hooked method will not execute. If you're trying to stop subsequent hooks from firing then have a look at $event->cancelHooks (https://processwire.com/api/ref/hook-event/)

  • Thanks 1
Posted

And it seems to work perfectly using $event->cancelHooks!

Thanks @Robin S for the pointer and for clarifying about replace, reading again from the doc it does say that it replaces the hookable function but it doesn't mean it will stop the functions hooked after.

  • Like 1

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
×
×
  • Create New...