Welcome Guest, Not a member yet? Register   Sign In
Best practice for a clean URL
#1

[eluser]patrick24601[/eluser]
I am building a fairly typical shopping site with categories and products. Since I am new to CI most of my URLs are pretty standard:

sitename.com/category/browse/1/category-name-goes-here-for-seo
sitename.com/product/browse/100/product-name-goes-here-for-seo

What is the best way to eliminate some of those nodes to get that SEO informatio close to the sitename.com i.e.

sitename.com/category-name-goes-here // would be ideal
sitename.com/1/category-name-goes-here // also good
sitename.com/category/category-name-goes-here

Any of these would work.

Thanks in advance for helping this n00b
#2

[eluser]TaylorOtwell[/eluser]
What about a route like:

Code:
$route['category/:any'] = "category/browse";

The guide on URI Routing will probably be helpful in this area. You can check it out here.
#3

[eluser]pbreit[/eluser]
Can you have dashes in path segments?
#4

[eluser]Crimp[/eluser]
You can have all allowed URI chars set in the config file.
#5

[eluser]patrick24601[/eluser]
Thanks for the help everybody. Since I still need a category number to get the category information my URLs would realistically have to look like:

example.com/category-name-goes-here/category/1

Which it looks like I can add a rule: ":any/category/:num"
and make that rule map to: "category/browse/$2"

I would not really ever need $1 because it is just the name I was using for SEO purposes.

Does this look correct? Would I use :num or (:num) ?
#6

[eluser]Twisted1919[/eluser]
You don't really need any category_id in the url at all.
In a weekend site that i worked, and finished it 5 minutes ago, i had to deal with category and products also, and my final urls are like :
Code:
// For listing products from acertain category
http://www.website.com/categories/category-unique-name.html
// Viewing a product
http://www.website.com/categories/category-unique-name/product-category-unique-name.html

This is great for SEO, as you have the url very descriptive.
In the database, you would add a url field and index it, for category and for product, then you will be sure that when adding categories, the generated url(which is the name transformed with url_title() function) is unique . The same you would do for products, but be sure that the product name is unique for a category so that you can have two products with same name in distinct categories.
Also, here is my code ;
Code:
//Categories Controller
    public function index()
    {
        $route          = $this->uri->segment(3,'index');
        $category_url   = $this->uri->segment(2);
        $product_url    = $this->uri->segment(3);
        
        if(empty($category_url) ||  ! $cdata = $this->mdl->get_category_by_url($category_url))
        {
            redirect('products');
        }
        $this->load->model('products/products_model','pmdl');
        $this->data['cdata']    = $cdata ;
        //view the products from a certain category
        if($route == 'index')
        {
            $numrows = $this->pmdl->count($cdata->category_id);
            $this->per_page = 12 ;
            
            $this->load->library('pagination');
            $config['base_url']        = rtrim(site_url(),'/').'/categories/'.$category_url.'/index/';
            $config['total_rows']      = $numrows ;
            $config['per_page']        = $this->per_page ;
            $config['uri_segment']     = 4;
            $config['num_links']       = 2;
            $config['cur_tag_open']    = '| <strong>';
            $config['cur_tag_close']   = '</strong>&nbsp;';
            $config['prev_tag_open']   = '';
            $config['prev_tag_close']  = '';
            $config['next_link']       = '&raquo;';
            $config['prev_link']       = '&laquo;';
            $config['next_tag_open']   = '';
            $config['next_tag_close']  = '';
            $config['full_tag_open']   = '';
            $config['full_tag_close']  = '';
            $config['num_tag_open']     = '|';
            $config['num_tag_close']    = '';
            $config['last_link']       = '';
            $config['last_link']       = '';
            $config['first_link']       = '';
            $config['first_link']       = '';
            $this->pagination->initialize($config);
            $this->data['pagination'] = $this->pagination->create_links();
            $segment = intval($this->uri->segment(4,0));
            $this->data['records'] = $this->pmdl->get_products($segment,$this->per_page,$cdata->category_id);
            $images = array();
            if($this->data['records'])
            {
                foreach($this->data['records'] AS $p)
                {
                    $images[$p->product_id] = $this->pmdl->get_product_images($p->product_id,1);
                }
            }
            $this->data['images'] = $images ;
            $this->template->load('categories/index',$this->data);            
        }
        else
        {
            if( ! $data = $this->pmdl->get_product_by_url($product_url,$cdata->category_id))
            {
                redirect('products');
            }
            
            $this->data['images']   = $this->pmdl->get_product_images($data->product_id,3);
            $this->data['data']     = $data;
            //next/prev products
            $this->data['next']     = $this->pmdl->get_next_product($data->product_id,$data->sort_order,$cdata->category_id);
            $this->data['prev']     = $this->pmdl->get_prev_product($data->product_id,$data->sort_order,$cdata->category_id);
            //3 recommended products from each category .
            $categories = $this->mdl->get_all(2);
            $recommended = $images = array();
            foreach($categories AS $c)
            {
                if($recommended[$c->url] = $this->pmdl->get_recommended_products($data->product_id,$c->category_id))
                {
                    foreach($recommended[$c->url] AS $p)
                    {
                        $images[$p->product_id] = $this->pmdl->get_product_images($p->product_id,1);
                    }
                }
            }
            $this->data['rec_images']      = $images ;
            $this->data['recommended'] = $recommended;
            $this->template->load('products/view',$this->data);
        }
    }

Hope it helps you, if you need any more info, just let me know.
#7

[eluser]Twisted1919[/eluser]
Ah, not to forget, the categories controller also has a remap method as follows :
Code:
public function _remap($method)
    {
        if(method_exists($this,$method))
        {
            $this->$method();
        }
        else
        {
            $this->index();
        }
    }

This will send every request to the index method .
#8

[eluser]patrick24601[/eluser]
So your primary lookup then becomes a long text string (url) and not what most people use which is a category or product number?

Pretty cool. Thanks.
#9

[eluser]Twisted1919[/eluser]
Something like that, you index the url of the category/product and when you check if that category/product exists, you check against the url, and from same query you return the category_id/product_id so that in the next queries you will use the category_id/product_id because you will need to join tables and you need to do it by using the id .

The performance is the same as using an ID in the url(because you request only ONE row, and the WHERE condition is looking for an indexed field), only that is way nicer.




Theme © iAndrew 2016 - Forum software by © MyBB