Jump to content

Recommended Posts

Posted

Good day!

I need to render a page output for a given url segment from API. There is a way to render a page with $page->render() and now with $page->renderPage(). But I can't find a way to render a page passing in an url segment. So the output would be not of site.com/page but of site.com/page/urlsegment to make it more clear.

Please share your ideas.

Posted

Do you mean something like this ?

$segments = ['earth', 'mars', 'jupiter'];

$wire->addHook('(/.*)/(' . implode('|', $segments) . ')', function (HookEvent $event) use ($segments) {
    $path = $event->arguments(1) . '/';

    try {
        $page = $event->pages->get($path);
    } catch (\Throwable $th) {
        $page = new NullPage();
    }

    if ($page->id) {
        header('Content-Type: application/json');
        echo json_encode([
            'path' => $path,
            'segment' => $event->arguments(2),
            'segments' => $segments,
            'page' => $page->title
        ]);
        exit;
    }
});

---

$segment = 'get';
$uri = $_SERVER['REQUEST_URI'] ?? '';
if (str_ends_with(rtrim($uri, '/'), $segment)) {
    $wire->addHook($uri, function (HookEvent $event) use ($segment, $uri) {
        list($path, $empty) = explode($segment, $uri);
        try {
            $page = $event->pages->get($path);
        } catch (\Throwable $th) {
            $page = new NullPage();
        }

        if ($page->id) {
            header('Content-Type: application/json');
            echo json_encode([
                'path' => $path,
                'segment' => $segment,
                'page' => $page->title
            ]);
            exit;
        }
    });
}

This will add a global url hook for url ends with requested segments and you can get page from first url segment than you can print anything you want.

  • Like 1
Posted

Thanks Iskender!

But that is not exactly what I am after. I need to render a page Page::renderPage hook and replace the output with another page render.

wire()->addHookBefore('Page::renderPage', function (HookEvent $event) {

	/* CONDITIONS CHECKING */

	$event->removeHook(null); // Remove this hook so we do not get caught up in a loop. See https://processwire.com/api/ref/wire/remove-hook/			
	$someOtherPage = wire()->pages->get(...); // Get the page to be rendered instead of the current one

	$event->return = $someOtherPage->render(); // HERE I NEED TO RENDER A PAGE OTPUT FOR AN URL SEGMENT INSTEAD OF REGULAR RENDER

	$event->replace = true;

	...

 

Posted

@Ivan Gretsky

Just use Page::render

$wire->addHookBefore('Page::render', function (HookEvent $event) {

    /**
     * @var Page $page
     * @var WireInput $input
     */
    $page = $event->object;
    $input = $event->wire()->input;

    // Use get method: // example.test/about?segment=home
    $segment = $input->get('segment');
    // Allow template url allow segments otherwise you will get 404 error
    $segments = $input->urlSegments();
    // Validate by template
    $page->template->name != 'home';

    if ($segment === 'home' || $page->template->name != 'home') {
        /** @var Page $home */
        $home = $event->wire()->pages->get(1);
        $event->replace = true;
        $event->return = $home->render();
    }
});

 

  • Like 1
Posted

Thank you friends! This approach works. The only thing I had to change using $input->setUrlSegment(1, "segment"); instead of dynamic property setting to get rid of warnings in PHP 8.2.

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
  • Recently Browsing   0 members

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