Welcome Guest, Not a member yet? Register   Sign In
regarding URLs / Titles
#1

Hello,

I inherited the task of maintaining a page for a small, niche-market classic car dealership that was done in CI with HTML, CSS layout and a mySQL DB...Not entirely over my head, but I'd be lying if I said I had a lot of previous experience with MVC. Anyow, the site is fairly basic, and is mostly composed of details about each car, and slider photo galleries along with basic inquiry forms.

The dev wrote an Admin panel of sorts that lets you quickly add and subtract vehicles, but it offers very little outside of that in terms of doing any quick customizations and the like.

So, with that, one of the issues I am facing with the site in it's current form is page titles....Currently, each vehicle profile page has a page title like "www.blahblahblah.com/index.php/inventory/detail/69"

This appears to be bad for SEO purposes, so my question is, what would it take to get CI to use the vehicle's title (i.e. 1959 Roll-Royce Phantom) to be used for the URL - like ""www.blahblahblah.com/index.php/inventory/detail/1959-rolls-royce-phantom"

If someone could point me in the direction of help files or guides related to these types of topics I would greatly appreciate it - very very eager to learn, thanks!

I have also been tasked with creating a new website or the same company, and would like to use CI, as there seems to be less overhead than a platform like Wordpress. Thanks again for any help here!
Reply
#2

The docs: http://www.codeigniter.com/docs
Some high points, assuming you're using CI3:
- Overview: http://www.codeigniter.com/user_guide/ov...index.html
- Tutorial: http://www.codeigniter.com/user_guide/tu...index.html
- CodeIgniter URLs: http://www.codeigniter.com/user_guide/general/urls.html
- URI Routing: http://www.codeigniter.com/user_guide/ge...uting.html
- Controllers: http://www.codeigniter.com/user_guide/ge...llers.html

More than likely, index.php/inventory/detail/69 is routing to a controller named Inventory and passing 69 to a method named detail(). The best way to change this to handle a URL like "www.blahblahblah.com/index.php/inventory/detail/1959-rolls-royce-phantom" would be to start with the detail() method.

More than likely the number is going to be a key value, and the detail() method will load a model and call a method on the model to look up the details of the car based on that key. Take a look at the model and determine whether it already has a method to look up the details based on the vehicle's title in the form you will be able to use in the URL. If it does, this is going to be an easy process. I would most likely attempt to retrieve the vehicle by title given the input. If that fails and the input is numeric, attempt to look it up by key. If the key lookup succeeds, I would grab the title from the returned data and redirect to the titular form of the URL, or use it to supply a canonical URL for SEO.

If the model doesn't have a method to look up the vehicle by title, or the titles in the database aren't suitable for use in a URL, you will probably need to modify the model to provide that functionality. You may also decide to modify the database to add a column to store URL-friendly titles to make the lookup process easier.
Reply
#3

(10-28-2015, 12:57 PM)mwhitney Wrote: The docs: http://www.codeigniter.com/docs
Some high points, assuming you're using CI3:
- Overview: http://www.codeigniter.com/user_guide/ov...index.html
- Tutorial: http://www.codeigniter.com/user_guide/tu...index.html
- CodeIgniter URLs: http://www.codeigniter.com/user_guide/general/urls.html
- URI Routing: http://www.codeigniter.com/user_guide/ge...uting.html
- Controllers: http://www.codeigniter.com/user_guide/ge...llers.html

More than likely, index.php/inventory/detail/69 is routing to a controller named Inventory and passing 69 to a method named detail(). The best way to change this to handle a URL like "www.blahblahblah.com/index.php/inventory/detail/1959-rolls-royce-phantom" would be to start with the detail() method.

More than likely the number is going to be a key value, and the detail() method will load a model and call a method on the model to look up the details of the car based on that key. Take a look at the model and determine whether it already has a method to look up the details based on the vehicle's title in the form you will be able to use in the URL. If it does, this is going to be an easy process. I would most likely attempt to retrieve the vehicle by title given the input. If that fails and the input is numeric, attempt to look it up by key. If the key lookup succeeds, I would grab the title from the returned data and redirect to the titular form of the URL, or use it to supply a canonical URL for SEO.

If the model doesn't have a method to look up the vehicle by title, or the titles in the database aren't suitable for use in a URL, you will probably need to modify the model to provide that functionality. You may also decide to modify the database to add a column to store URL-friendly titles to make the lookup process easier.

wow, thank you so much for your help with this - I have unfortunately got called on to perform other duties today (I essentially handle all IT/Tech duties for the company), but I am going to take a look at this tonight from home.

In the meantime, here is the "details" controller / page code for each vehicle:

Code:
<?php $this->load->view('_inc/_head'); ?>

<div id="detail" class="grid_10 push_1">

<h1><?php echo $record->production_year . " " . $record->make . " "  . $record->model; ?></h1>

<?php
$spec_keys = array(
'stock',
'current_condition',
'performance',
'performance_options',
'transmission',
'suspension',
'color_exterior',
'color_interior',
'features',
'options',
'optional_equipment',
'mileage',
'wheels',
'tires',
'brakes',
'vin_num',
'engine_num',
'gearbox_num',
'other_1',
'other_2',
'other_3'
);
?>

<table title="Specifications" class="grid_6 alpha">
<tr>
<td><h5>Specifications</h5></td>
</tr>
<?php foreach ($spec_keys as $k) : if($record->$k != "") : ?>
<tr>
<td><?php echo ucfirst(str_replace('num', '#', str_replace('_', ' ', $k))); ?>:</td>
<td><?php echo $record->$k; ?></td>
</tr>
<?php endif; endforeach; ?>
</table>


<img class="grid_4 omega" src="<?php echo base_url(); ?>/gallery/<?php echo $record->stock . "/" . $record->stock; ?>.jpg" />
<div class="clear"></div>


<ul class="buttons">
<li><?php echo anchor('inventory/index','« Back',''); ?></li>
<li><?php echo anchor("contact/buyer/$record->id",'Serious Buyer','class="pop_form"'); ?></li>
<li><?php echo anchor("contact/inquire/$record->id",'Inquire','class="pop_form"'); ?></li>
<li><?php echo anchor(base_url() . "gallery/" . $record->stock,'View Gallery','target="_blank"'); ?></li>
<?php
$video_formats = array(
'wmv',
'mov',
'mpg',
'mp4'
);
$video_found   = false;
$video_name    = "gallery/" . $record->stock . "/" .$record->stock . "-vid";

foreach ($video_formats as $format) {
   $file = $video_name . "." . $format;
if (file_exists("$file")) {
echo '<li><a href="' . base_url() . $file . '" class="pop_video">Video</a></li>' . "\n";
break;
}
}
?>
</li>
</ul>


<div class="clear"></div>

<h5>Description</h5>
<p><?php echo $record->description; ?></p>
<h5>History</h5>
<p><?php echo $record->history; ?></p>
<?php
 $image_formats = array(
  'jpg',
  'JPG',
  'gif',
  'png'
 );
 $auth_found     = false;
 $file_name = "gallery/" . $record->stock . "/" .$record->stock . "-auth";

 foreach ($image_formats as $format) {
     $file = $file_name . "." . $format;
  if (file_exists("$file")) {
       $str  = "";
       $str .= "<h5>Authenticity</h5>\n";
  $str .= '<p><img src="' . base_url() . $file . '" width="300" /></p>' . "\n";
  echo $str;
  break;
  }
}?>
<?php

/*

echo $record->restoration_candidate;
echo $record->authenticity_url;

*/
?>

</div><!-- eo #detail -->
<?php $this->load->view('_inc/_foot'); ?>

and here is the "inventory" controller/page code:

Code:
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');

class Inventory extends CI_Controller {

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

 public function index() {
   $data = array();

   if($query = $this->inventory_model->get_inventory()) {
     $data['records'] = $query;
     $data['makes']   = $this->inventory_model->get_makes();
   }
   $this->load->view('inventory/index_page', $data);
 }

public function make() {
$data  = array();
$query = "";
$make  = urldecode($this->uri->segment(3));

$query = ($make) ? $this->inventory_model->get_records_of_make() : "";


if($query) {
$data['records'] = $query;
$data['makes']   = $this->inventory_model->get_makes();
$this->load->view('inventory/index_page', $data);
} else {
redirect('inventory');
}

}

public function archived() {
$query = $this->inventory_model->get_archived();

if($query) {
$data['records'] = $query;
$data['makes']   = $this->inventory_model->get_makes();
$this->load->view('inventory/index_page', $data);
} else {
redirect('inventory');
}

}

 public function detail() {
   $data['record'] = $this->inventory_model->get_record();
   $this->load->view('inventory/detail_page', $data);
 }

}

?>


Many many thanks once again and I'll see what I can accomplish later this evening. The other thing that has been a debacle to get going is a recaptcha on the details page inquiry form, but that 's likely my just incompetence with CI  Confused
Reply
#4

Back to work here, yesterday I posted the incorrect code for the Inventory controller. From my limited experience, I am not seeing anything in the CI controller or the DB with respect to titles - here is the Inventory controller:

Code:
class Inventory extends CI_Controller {

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

 public function index() {
   $data = array();

   if($query = $this->inventory_model->get_inventory()) {
     $data['records'] = $query;
     $data['makes']   = $this->inventory_model->get_makes();
   }
   $this->load->view('inventory/index_page', $data);
 }

public function make() {
$data  = array();
$query = "";
$make  = urldecode($this->uri->segment(3));

$query = ($make) ? $this->inventory_model->get_records_of_make() : "";


if($query) {
$data['records'] = $query;
$data['makes']   = $this->inventory_model->get_makes();
$this->load->view('inventory/index_page', $data);
} else {
redirect('inventory');
}

}

public function archived() {
$query = $this->inventory_model->get_archived();

if($query) {
$data['records'] = $query;
$data['makes']   = $this->inventory_model->get_makes();
$this->load->view('inventory/index_page', $data);
} else {
redirect('inventory');
}

}

 public function detail() {
   $data['record'] = $this->inventory_model->get_record();
   $this->load->view('inventory/detail_page', $data);
 }

}

?>

Here's a few screengrabs from the current DB, which has the vehicles by stock number, year, make, model:

[Image: AsXnI2E.png]

[Image: s7l21Km.png]

The head include does include a title tag, but outside of that I see nothing with respect to URLs. 

Thanks for any feedback here, the documentation is helpful, but rather daunting at this stage!
Reply
#5

OK, first, it looks like your detail method in the Inventory controller calls your Inventory_model's get_record() method, but the controller doesn't grab the number from the URL, so I'm guessing the model is doing that (in a perfect world the model wouldn't do that, but it looks like your model may be doing that in get_records_or_make() and get_archived(), as well).

Since you don't have a field in the database that's already populated with the information you want to use in the URL, you have to decide whether you want to specify a way to map the URL to fields in the database, or create a new column to use to lookup the correct entry in the database. For example, if you go to "/inventory/detail/1959-rolls-royce-phantom", you could do something like this:

PHP Code:
$lookup $this->uri->segment(3);
$lookupValues explode('-'$lookup);
// Now $lookupValues is array('1959', 'rolls', 'royce', 'phantom') 

The problem should be readily apparent, as you have the year (1959), but the make, 'rolls-royce' (I'm assuming), is split across two entries in the array, while other makes would be a single entry, and still others might be more, and the model would have the same issue.

One common approach to solving this problem is to create a "slug" (what I previously referred to as a title) from the fields and insert that as a new column in the database. So, your new column would have a value of '1959-rolls-royce-phantom' for that particular row in the database (you could write a script to populate this column after creating it in the database, using the production_year, make, and model to build the "slug"; the url_title() function in CI's URL helper tends to be very useful for something like that).

Another alternative is to change the URL format that you would like to use. For example, you could use "/inventory/detail/1959/rolls-royce/phantom". Then you could do something like this:

PHP Code:
$year $this->uri->segment(3);
$make $this->uri->segment(4);
$model $this->uri->segment(5); 

or even:
PHP Code:
public function detail($year$make$model

It looks like your model's get_makes() method might already do something to deal with looking up the make from the URL, but the make() method of the controller uses urldecode($this->uri->segment(3)), which tells me the model's method may not be SEO-friendly. So, you might still need a column (or two) to hold SEO-friendly versions of the make (and probably model) names, or a lookup table (or two) to map the SEO-friendly names to the names used in the existing make and model columns.
Reply




Theme © iAndrew 2016 - Forum software by © MyBB