Welcome Guest, Not a member yet? Register   Sign In
CI is adding URL parts to links
#1

(This post was last modified: 11-13-2014, 02:18 AM by milosh.)

Hello,

I am fairly new to CI and have a problem that is driving me crazy. On my site I have a top navigation for categories, like download, home and so on and each category has a sidebar menu that belongs to the category.

Because I don't want to add a controller for every category, I am trying to do it with a generic controller and view, the model gets the right data for the sidebar menu.

A typical top link would be: domain.ch/home or domain.ch/unix

A typical sidebar link would be:
domain.ch/home/news or
domain.ch/unix/oneliners

Everything after the first / are arguments for the controller because I route the requests to it:

$route['default_controller'] = 'pages/index';
$route['(:any)/(:any)'] = 'pages/index/show/$1/$2';
$route['(:any)'] = 'pages/index/show/$1';

So I am always calling the controller "pages", method "index" with the argument "show" (which loads the show.php view) and one or two optional parameters. The first optional is always the category, the second the section which corresponds to a sidebar link.

Therefor when I click on "home/news" in the sidebar, it should route to "pages/index/show/home/news". The model pulls the right data for the news section belonging to the category home.

Now for the driving-me-crazy-part: This works for the first time I access the site:
click on toplink unix -> sidebar with correct links for unix is shown
click on toplink home -> sidebar with correct links for home is shown
click on sidebar link home/news -> great, the news are pulled and showed on the side.
click again on sidebar link home/news -> 404 page not found. The reason being, that CI is putting another "home" before "home/news", turning the link into "home/home/news". This is only seen in the browser while hoovering over the link. The HTML still shows only "home/news". So for some reason, CI seems to alter the base url and adds the category name to my links every time I click on a link.

I hope someone can hint me in the right direction, I've spend already 10 hours chasing this bug in my code. Is there something wrong with the whole concept how I want to achieve a database driven generic menu or am I missing something? I suspect it's something with routing or .htaccess but I tried virtually everything I could find on google and nothing solved the problem.

Here are the relevant files:
.htaccess:
Options -MultiViews
RewriteEngine On
Options -Indexes
RewriteBase /

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-l
RewriteRule ^(.*)$ index.php/$1 [L]

routes.php:
$route['default_controller'] = 'pages/index';
$route['(:any)/(:any)'] = 'pages/index/show/$1/$2';
$route['(:any)'] = 'pages/index/show/$1';

Pages.php (controller)
<?php
class Pages extends CI_Controller {

public function __construct()
{
parent::__construct();
$this->load->model('home_model');
}

public function index($page = 'show', $category = 'home' , $section = NULL)
{
$data['toplinks'] = $this->home_model->get_toplinks();
$data['sidelinks'] = $this->home_model->get_sidelinks($category);
$data['articles'] = $this->home_model->get_articles($section);
$data['page'] = $category;
$data['title'] = ucfirst($category); // Capitalize the first letter

$this->load->view('templates/header', $data);
$this->load->view('templates/navigation', $data);
$this->load->view('pages/show', $data);
$this->load->view('templates/footer', $data);

}

}

navigation.php: (top/sidebar view)
<div id="topnav">
<?php foreach ($toplinks as $item): ?>
<a href="<?php echo $item['link'] ?>" target="_self"><?php echo $item['text'] ?></a>
<?php endforeach ?>
</div>
<hr>
<div id="leftnav">
<table>
<?php foreach ($sidelinks as $item): ?>
<tr><td>
<a href="<?php echo $page.'/'.$item['link'] ?>" target="_self"><?php echo $item['text'] ?></a>
</td></tr>
<?php endforeach ?>
</table>
</div>

TL;DR: go to http://domain.ch and click several times on "News" in the left sidebar menu, observe the browser address window while hovering with the mouse. Everytime one clicks on news, a new "home" is getting infront of the path, /home/news -> /home/home/news and so on. Why is this happening?

Thank you very much Wink
Reply
#2

This is most likely due to how you're creating the links. They are being created without a '/' at the beginning, so the URL is being added onto the current URL as a relative location. If all of the links started with a '/' they would all start at the site root and you wouldn't experience that.

An even better method, though, is to use the URL helper's `site_url()` method with the page link inside of that, like:

Code:
<a href="<?php echo site_url($page.'/'.$item['link']) ?>" target="_self"><?php echo $item['text'] ?></a>


That way if the settings ever change, or if it has to be moved to a subdomain, or if the config gets accidentally tweaked and you suddenly have 'index.php' in the URL again, your links will still work.
Reply
#3

Thank you so very much kilishan, you saved my sanity, it finally works Big Grin

I suspected something the like but didn't know what exactly to do about it. Being new to CI and MVC frameworks in general I was not confident enough in my code to be sure that it's working as it's supposed to.

So now that the proof-of-concept works I can finally get to work and build the site Wink

Btw in case any CI devs stumble upon this thread: awesome framework, it's real fun to work with it and it truly saves time. I'm also learning OO with the framework, it makes the whole topic very accessible because it's so well structured. And as a rather old-school unix guy I love the ban of camelCase in the code, the method names read like my shell functions Big Grin
Reply
#4

(11-07-2014, 12:29 PM)milosh Wrote: And as a rather old-school unix guy I love the ban of camelCase in the code, the method names read like my shell functions Big Grin

Cool I'm an old school C developer on unix and I hate camelCase too ! Cool
Reply
#5

@milosh - I'm glad it worked things out for you!

I've always preferred the readability of the current CI code style myself, though I've done enough work with PSR-2 compliant code that either way works. camelCase is definitely more difficult to quickly scan, IMO.
Reply




Theme © iAndrew 2016 - Forum software by © MyBB