Link to home
Start Free TrialLog in
Avatar of Crazy Horse
Crazy HorseFlag for South Africa

asked on

remove 'pages' from url path pages/contact-us in mvc

I am trying to understand how I can change the way the routing works in this tutorial that I did.

Currently, if you go to a contact page for example, the url looks like:

mysite.com/pages/contact-us

I understand that I have a views folder with another folder called 'pages' in it, and I have a pages controller that sends the data to that view:

$this->view('pages/contact-us', $data);

Open in new window


That's fine and it makes sense. But I don't want it to look like that. I would rather it was just mysite.com/contact-us without having to have the /pages/

I am not sure what code would be required to post here so I am going to post what I think will be helpful.

In my root folder with my index.php I have a .htaccess file

<IfModule mod_rewrite.c>
 RewriteEngine on
 RewriteRule ^$ public/ [L]
 RewriteRule (.*) public/$1 [L]
</IfModule>

Open in new window


In my public folder I have another .htaccess

<IfModule mod_rewrite.c>
 Options -Multiviews
 RewriteEngine On
 RewriteBase /jonomvc/public
 RewriteCond %{REQUEST_FILENAME} !-d
 RewriteCond %{REQUEST_FILENAME} !-f
 RewriteRule ^(.+)$ index.php?url=$1 [QSA,L]
 </IfModule>

Open in new window


In my pages controller I have:

public function contact_us() {
		
		$data = [
			
			'title' => 'Contact us'
		];
		
		$this->view('pages/contact-us', $data);
}

Open in new window


And this is my core class:

class Core {
	
	protected $currentController = 'Pages';
	protected $currentMethod = 'index';
	protected $params = [];
	
	public function __construct() {
		$url = $this->getUrl();
		
		// Look in Controllers for first value
		if(file_exists('../app/controllers/' . ucwords($url[0]) . '.php')) {
			//if exists, set as controller
			$this->currentController = ucwords($url[0]);
			// Unset zero index
			unset($url[0]);
		}
		
		// Require the controller
		require_once '../app/controllers/' . $this->currentController . '.php';
		
		// Instantiate controller
		$this->currentController = new $this->currentController;
		
		// Check for second part of url
		if(isset($url[1])) {

			$url[1] = str_replace('-', '_', $url[1]);
			
			// check to see if method exists in controller
			if(method_exists($this->currentController, $url[1])) {
				$this->currentMethod = $url[1];
				// Unset 1 index
				unset($url[1]);
			}	
		}
		
		// Get params
		$this->params = $url ? array_values($url) : [];
		
		// Call a callback with array of params
		call_user_func_array([$this->currentController, $this->currentMethod], $this->params);
	}
	
	public function getUrl() {
		if(isset($_GET['url'])) {
			$url = rtrim($_GET['url'], '/');
			$url = filter_var($url, FILTER_SANITIZE_URL);
			$url = explode('/', $url);
			return $url;
		}
	
	}
}

Open in new window

ASKER CERTIFIED SOLUTION
Avatar of Julian Hansen
Julian Hansen
Flag of South Africa image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of Crazy Horse

ASKER

Thank you Julian,

To simplify I am just going to call it contact instead of contact-us.

I created the controller in the controllers folder called 'Contact.php'

In that file I put:

class Contact extends Controller {
	
	public function __construct() {
		
		
	}
	
	public function contact() {
		
		$data = [
			
			'title' => 'Contact us'
		];
		
		$this->view('contact', $data);
	}
}

Open in new window


If the contact page was sitting inside my 'pages' folder, inside of my 'views' folder then I would have used:

$this->view('pages/contact', $data);

Open in new window


But since I don't want the /pages/ part, I put the contact.php into the root of the 'views' folder instead of 'views/pages' folder, but that does't seem to work e.g.:

$this->view('contact', $data);

Open in new window


The error is:

Warning: call_user_func_array() expects parameter 1 to be a valid callback, class 'Contact' does not have a method 'index' in /Applications/MAMP/htdocs/mysite/app/libraries/Core.php on line 54

Line 54:

call_user_func_array([$this->currentController, $this->currentMethod], $this->params);

Open in new window


Sorry if I am being dof, but I am still trying to wrap my head around all of this.
What the error is saying is that it can't find a method index in the controller.

I did a lot of guessing filing in the gaps so there might be some implementation steps that need to be done as well.

But since I don't want the /pages/ part, I put the contact.php into the root of the 'views' folder instead of 'views/pages' folder, but that does't seem to work e.g.:

I would have expected that the controller would have been in the same folder as pages - again I am guessing here but if it is in your views folder then I don't see how it is going to be found
/root
    /pages
        /contact-us

Open in new window

Found with url /pages/contact-us

Therefore I am guessing that /contact would be

/root
    /pages
        /contact-us.php
    /contact.php

Open in new window

The folder structure looks like this in the root:

app
public

Then in app:

/app
      /controllers
        Pages.php

          /views
                          /pages
                                about.php
                                index.php
       
So, the Pages.php in the controllers folder routes all the files in the views/pages directory

Pages.php controller:

class Pages extends Controller {
	
	public function __construct() {
		

	}
	
	public function index() {
		
		
		$data = [
				'title' => 'Welcome',
				];
		
		$this->view('pages/index', $data);
	}
	
	public function about() {
		
		
		$data = [
			
			'title' => 'About us'
		];
		
		$this->view('pages/about', $data);
	}

}
  

Open in new window

The I imagine you need a contact.php in the same folder as Pages.php to handle the routing for /contact.