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

LVL 1
Black SulfurAsked:
Who is Participating?
 
Julian HansenConnect With a Mentor Commented:
Seems to me you would need to put a controller in the controllers folder called contact-us.php and load your view from there.
Lines 7-11 of your last listing
public function __construct() {
		$url = $this->getUrl();
		
		// Look in Controllers for first value
		if(file_exists('../app/controllers/' . ucwords($url[0]) . '.php')) {

Open in new window

It uses the first element in the $url array. If we look at how that is contructed it is by exploding the url URL parameter.
We need to go back to the .htaccess to check what this is. Based on a URL of
mysite.com/pages/contact-us

Open in new window

The resulting $url array will be
Array
(
    [0] => pages
    [1] => contact-us
)

Open in new window

$url[0] is pages so from line 11 we get
if(file_exists('../app/controllers/PAGES.php')) {

Open in new window

Your new URL is
mysite.com/contact-us

Open in new window

$url[0] is now contact-us so line 11 would be
if(file_exists('../app/controllers/CONTACT-US.php')) {

Open in new window

So I am guessing if you create a controller CONTACT-US and then in there load your view you should be good to go.
0
 
Black SulfurAuthor Commented:
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.
0
 
Julian HansenCommented:
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

0
 
Black SulfurAuthor Commented:
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

0
 
Julian HansenCommented:
The I imagine you need a contact.php in the same folder as Pages.php to handle the routing for /contact.
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.