Welcome Guest, Not a member yet? Register   Sign In
A little help understanding the controller
#1

[eluser]intoitdaily[/eluser]
Alright so I'm new to CodeIgniter, but I'm learning fast, as it's so easy! But I'm wondering if this certain thing that I'm trying to do is possible.

I have a blog that I built (I originally followed the tutorial but I didn't like the way it was represented so I made my own modifications to better reflect the way a blog is supposed to look). Anyway, http://localhost/mysite/index.php/blog/ brings a list of blog posts. Each title has a link that takes you to http://localhost/mysite/index.php/blog/id/NUMBER (replacing NUMBER with the actual id of the blog entry in the database). Now, what I'd like to do, is be able to take out the /id/ of the URI. Like this: http://localhost/mysite/index.php/blog/3 and display the blog_id_view like it does now, only taking out the /id/... get it?

I tried putting something like this in the index() of the blog controller
Code:
if ($this->uri->segment(2)) {
    // only display single blog entry
    $this->db->where('id', $this->uri->segment(2));
    $this->db->where('published', 1);
    $data['blog_entry'] = $this->db->get('blog');
            
    $this->db->where('blog_post_id', $this->uri->segment(2));
    $data['blog_comments'] = $this->db->get('blog_comments');
            
    $this->load->view('blog_id_view', $data);
}
else {
    // pull up the list of all blog posts as normal...
    $this->db->order_by('id', 'desc');
    $this->db->where('published', 1);
    $data['blog_posts'] = $this->db->get('blog');
    
    $this->load->view('blog_view', $data);
}

But that didn't work. Something with the if-statement I think. Anyway that's just pseudo-code. i tried it a couple of days ago and just worked around it by adding function id() {} to my blog controller instead, this the http://localhost/mysite/index.php/blog/id/NUMBER... So, is there a way to do this? I figure if there is, I'll definitely become more familiar with the way controllers work and CodeIgniter in general. Thanks!
#2

[eluser]Thorpe Obazee[/eluser]
Use routing
#3

[eluser]TheFuzzy0ne[/eluser]
Did you know that you can parameters after the method name are passed in to the controller method as arguments?

Code:
class Blog extends Controller {

    function Blog()
    {
        parent:Controller();
    }

    function index()
    {
        $this->show();
    }
    function show($id=NULL)
    {
        if ($id)
        {
            $this->db->where('id', $id);
        }

        $data['blog'] = $this->db->get('blog');

        $this->load->view('blog_view', $data);
    }
}

Obviously it needs some extra validation in there, just in case the id is not valid or something, but hopefully it helps.

Sorry if I've missed the point completely...
#4

[eluser]xwero[/eluser]
TheFuzzy0ne there is no need to create a show method, just put the code in the index method.

bargainph is right you just have to route the url to go to the index function even with the id parameter.
Code:
$route['(blog/)(\d+)'] = '$1$2'; // i catch the controller because i don't want to repeat myself
And your controller looks like
Code:
class Blog extends Controller
{
   function index($id = '')
   {
       $this->load->model('blog_model','',true); // add 3th param if you don't autoload the database library
       if($id == '' OR ! is_numeric($id))
       {
           $data['posts'] = $this->blog_model->posts();
           $this->load->view('blog_view', $data);
       }
       else
       {
           $data['post'] = $this->blog_model->post($id); // returns row
          
           if( ! isset($data['post']->title)) // no title id must not exist
           {
               redirect('blog'); // url helper function
           }

           $data['comments'] = $this->blog_model->comments($id);

           $this->load->view('blog_id_view', $data);
       }
   }
}
#5

[eluser]Colin Williams[/eluser]
_remap() it. See the Controllers section of the User Guide, surprisingly...

Also see http://ellislab.com/forums/viewthread/87496/
#6

[eluser]xwero[/eluser]
I'm not that big on using _remap, it feels hackish. If it's hard to route put the routing in your controller.
#7

[eluser]Colin Williams[/eluser]
Because using a function for which it was intended is hackish? I don't follow.
#8

[eluser]xwero[/eluser]
from the user guide
Quote:If your controller contains a function named _remap(), it will always get called regardless of what your URI contains.
This means if you have a route to a method where the controller contains a _remap method the method gets routed twice. That is why it feels hackish.

I try to stay away as far as possible from everything that runs every time. Only if it needs to run every time then it's valid to use.
#9

[eluser]TheFuzzy0ne[/eluser]
I second that. I avoid _remap like the plague. It just doesn't "feel right" to me. I'm sure it's useful, but it's one of those functions I've always found an alternative to.
#10

[eluser]Colin Williams[/eluser]
I guess how I see it is that on some occasions, when the existing convention of /controller/function/params does not fit your need, the only way to subvert the convention is through 1.) routing, 2.) _remap() or 3.) overloading the Input class. When routing is not enough, _remap seems just right. Seems some people jump from 1 to 3.

And the key to _remap is writing it in a way that doesn't create a restrictive new convention. In other words, you don't want to have a remap function that you have to modify each time you add a function to the controller. So maybe anyone not comfortable/confident in doing that should run and hide, I guess.




Theme © iAndrew 2016 - Forum software by © MyBB