skip to Main Content

I am working on a basic blog application in Codeigniter 3.1.8 and Bootstrap 4.

I have been working for some time on this application and consequently, it has a lot of features. Most of these rely on the ids of posts, pages, etc.

For SEO purposes, I would like to use friendly URLs, instead of ids to display the individual posts, so I have added a slug column to the posts table.

enter image description here

The slugs are made from post titles, with this chunks of code in the Posts_model model and the Posts controller, respectively.

From the model:

public function slug_count($slug){
    $this->db->select('count(*) as slugcount');
    $this->db->from('posts');
    $this->db->where('slug', $slug);
    $query = $this->db->get();
    return $query->row(0)->slugcount;
}

public function create_post($post_image, $slug) {
    $data = [
        'title' => $this->input->post('title'),
        'slug' => $slug,
        'description' => $this->input->post('desc'),
        'content' => $this->input->post('body'),
        'post_image' => $post_image,
        'author_id' => $this->session->userdata('user_id'),
        'cat_id' => $this->input->post('category'),
        'created_at' => date('Y-m-d H:i:s')
    ];
    return $this->db->insert('posts', $data);
} 

From the controller:

// Create slug (from title)
$slug = url_title($this->input->post('title'), 'dash', TRUE);
$slugcount = $this->Posts_model->slug_count($slug);
if ($slugcount > 0) {
    $slug = $slug."-".$slugcount;
}

To achieve my SEO goal, I have considered and tried out the approach in this tutorial but since there are numerous functionalities needing ids (deleting posts via AJAX, for example) and other that do not require slugs (editing posts) I am unable (and unwilling) to substantially modify the post viewing method in the controller,

public function post($id) {
    $data = $this->Static_model->get_static_data();
    $data['pages'] = $this->Pages_model->get_pages();
    $data['categories'] = $this->Categories_model->get_categories();
    $data['posts'] = $this->Posts_model->sidebar_posts($limit=5, $offset=5);
    $data['post'] = $this->Posts_model->get_post($id);

    if ($data['categories']) {
        foreach ($data['categories'] as &$category) {
            $category->posts_count = $this->Posts_model->count_posts_in_category($category->id);
        }
    }

    if (!empty($data['post'])) {
        // Overwrite the default tagline with the post title
        $data['tagline'] = $data['post']->title;

        // Get post comments
        $post_id = $data['post']->id;
        $data['comments'] = $this->Comments_model->get_comments($post_id);

        $this->load->view('partials/header', $data);
        $this->load->view('post');
    } else {
        $data['tagline'] = "Page not found";
        $this->load->view('partials/header', $data);
        $this->load->view('404');
    }
    $this->load->view('partials/footer');
} 

and the corresponding code in the model:

public function get_post($id) {
    $query = $this->db->get_where('posts', array('id' => $id));
    if ($query->num_rows() > 0) {
        $data = $query->row();
        // run separate query for author name
        $author_query = $this->db->get_where('authors', array('id' => $data->author_id));
        if ($author_query->num_rows() == 1) {
            $author = $author_query->row();
            $data->first_name = $author->first_name;
            $data->last_name = $author->last_name;             
        } else {
            $data->first_name = 'Unknown';
            $data->last_name = '';
        }
        return $data;
    }
}

What would be a simple, less “intrusive” approach to replace post id with slug in the singe post view only?

3

Answers


  1. Well, I think you can have both the id and the slug on the same function/url eg /id/slug. This way, you always have your id and seo is happy too because the url has the page title(slug). Then on your function, you can have public function post($id,$slug="") {.

    Login or Signup to reply.
  2. Update in model

    replace

    public function get_post($id) {
       $query = $this->db->get_where('posts', array('id' => $id));
    

    with

    public function get_post($slug) {
        $query = $this->db->get_where('posts', array('slug' => $slug)); 
    

    Update in Controller

    replace

    public function post($id) {
    

    with

    public function post($slug) {
    

    and replace

    $data['post'] = $this->Posts_model->get_post($id);
    

    with

    $data['post'] = $this->Posts_model->get_post($slug);
    
    Login or Signup to reply.
  3. Also update your routes for better user friendly url.

    //If you categorize your blog
    $route['blog-category/(:any)'] = 'blogController/blogFunction/$1';
    //this will accept any uri
    $route['(:any)/(:any)'] = 'blogController/blogFunction'
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search