Jump to content

I can't get rewriting the URL to work


desbest
 Share

Recommended Posts

I can't get rewriting the URL to work on processwire.

Below is my following code in runfirst.php template file that runs before any other template as defined in the config file with $config->prependTemplateFile = 'runfirst.php';

<?php
//url rewrite

// https://processwire.com/talk/topic/1799-routes-and-rewriting-urls/
function segmentUrl(HookEvent $event){
    $url = $event->return; // requested url
    $segment = "/page/";
    if(strpos($url,$segment) == 0){
        $event->return = str_replace(rtrim($segment,'/'),'/article/',$url);
    }
}


// https://processwire.com/talk/topic/2984-controlling-page-url-structure/
function hookPagePath(HookEvent $e) {
 $page = $e->object;
 // if($page->template == 'article') $e->return = "/article/$page->name/";
 $e->return = "/article/$page->name/";
}

// $wire->addHookAfter('Page::path', null, 'segmentUrl');
// $pages->addHookAfter('Page::path', null, 'hookPagePath');
?>

It doesn't matter which ->addHookAfter command I use, the page still does not rewrite. I have enabled URL segments on the template for the web page I am running.

What is going on and how do I fix it?

Link to comment
Share on other sites

Hello I checked, and I'm not calling my hook too late, because I put exit(); on runfirst.php, nothing displayed when running my website in the web browser. runfirst.php is running before every other template file runs.

I tried the code in hooks.php and it doesn't work.

I made a quick modification to what hooks.php to the page below, and it doesn't work.

wire()->addHookBefore('Page::path', function($event) {
  $page = $event->object;
  $event->replace = true;
  $event->return = "/x/$page->name/";
}); 

mod_rewrite is enabled and the URL of every page in my Processwire website isn't being rewritten.

I'm using Processwire 3.0.99

What is going on that isn't allowing me to rewrite the URL in Processwire?

Link to comment
Share on other sites

I've read all three threads and have these comments.

The pages on my website I want to write have a query string on the end, so I would like to rewrite the URL so instead of the URL saying /broker/?choice1=1206&choice2=1207&mode=cryptocurrency it instead says /compare/local-bitcoins-vs-cex-io ,so that means that the threads Virtual Parents and Hide Parent Page From URL are not suitable for my needs.

That leaves me with Routing and Rewriting URLs left to read. The only relevant post in the thread is this one, and I have followed those instructions (see first post above) and the route isn't created and the URL does not rewrite.

What is going on?

Link to comment
Share on other sites

I'm trying out these hooks myself to see if I can get them working, however based on your latest post I might suggest a different approach.

If you have URLs that are going to have that many query parameters and lots of variants, you might be better off writing code to process them using the `$input->get` variables and then redirect to the correct page using `$session->redirect()`. I presume if the query parameters have different values, they'll go to different destinations.

Alternately, if these are a lot of legacy URLs that you want redirected to new canonical pages, putting those redirects directly in .htaccess with mod_rewrite might be better (or using a redirect URLs plugin).

Link to comment
Share on other sites

This works for me when hooked in ready.php (see below). It looks like if you're hooking within a template include, it's too late in the ProcessWire startup / page delivery process. That's what @kongondo was referring to with "too late". It's more than just the order of the includes in the template file, or whether your script exits instead of continues.

Here's the code that worked for me in /site/ready.php:

<?php namespace ProcessWire;

function hookPath(HookEvent $event) {
	echo sprintf('The path is: %s', $event->return); exit;
}

$wire->addHookAfter('Page::path', 'hookPath');

I still think hooking like this to perform a redirect might be overkill for what you described in your last post.

Link to comment
Share on other sites

  • 1 month later...

Hello after the late reply,

I can't use that example of redirecting a URL with query strings to a static page, because the pages I would like to use URL rewriting for are not static pages, they are dynamically generated based on what is inside the query string.

See below for examples.

Cryptocurrency comparison: BVC vs Changelly // Binance vs Changelly

Forex comparison:  IC Markets vs AvaTrade  // EasyMarkets vs AvaTrade

Note the query string in the URL. I would like to rewrite the URL based on the query string, of which the content of the page is dynamically generated based on the query string.

Link to comment
Share on other sites

  • 3 weeks later...

Your first example isn't working for two reasons I can see. Though maybe these are ones you already know, but jut in case:  1) it needs to be in your /site/ready.php or /site/init.php file; 2) The addHookAfter() call is commented out, so it never gets hooked; 3) your str_replace() looks to me like it would result in 2 slashes being present at the end, rather than one (due to the rtrim). 

Another thing to consider is that $page->path() does not return a URL. It returns a page path. The might be the same in many instances, but if PW is running from a subdirectory, they won't. Also, neither are intended to be returning query strings, so it's kind of taking these methods outside the scope of what they are intended. Maybe it's okay to do, I'm not certain but I might suggest instead adding your own custom URL function or method, and using that to get these custom URLs for when you want them. For instance, you could add Page::myurl() method in your /site/init.php file: 

$wire->addHookMethod('Page::myurl', function($event) {
  $page = $event->object;
  $path = $page->path();
  // determine if it's a going to be a custom URL
  if(strpos($path, '/page/') === 0) {
    // replace /page/ with /article/
    list(,$path) = explode('/page/', $path, 2); 
    $path = "/article/$path";
  }
  // convert path to URL
  $url = $event->wire('config')->urls->root . ltrim($path, '/'); 
  // add in any query string params stored in $input->whitelist
  $queryString = $event->wire('input')->whitelist->queryString();
  if(strlen($queryString)) $url .= '?' . $queryString;
  // return the URL
  $event->return = $url;
}

Now, rather than calling $page->url(), you can call $page->myurl() for any of the cases where you want to use these custom URLs. 

Another strategy would be to change everything after the entire page has rendered, like with a after Page::render hook. Though I don't think I'd use that if your intention is to add query strings to URLs. 

  • 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...