开发者

Filter, sort and paginate in Codeigniter

Ive recently started using CodeIgniter as I was searching for a very lightweight framework and it seemed to come up as a top choice.

I am new to the whole MVC thing,开发者_C百科 enjoying it but am stuck with something which seems very simple.

I am coding a CMS and need a way to filter, sort and paginate the results. I am used to doing it with querystrings, so I would have something along the lines of:

articles.php?order=title&sort=desc&filter=articletitle&page=5

I have no idea how I would go about doing this in CI so I just turned on the EnableQueryStrings in the config and it works fine, but i am getting the feeling its probably not the most elegant solution.

I suppose I could have

index.php/articles/index/order/title/sort/desc/filter/articletitle/page/5

but to me this seems very inflexible, what if for example i dont need to sort, how would i make sure i am looking at the correct uri segment?

any ideas?


Have you tried implementing the _remap function? It will redirect all queries to the controller to that function allowing you to implement as many (or as few) of those as you like.

You could then do something like this:

class Articles extends Controller
{
    // Note: No need for a "order" or even an "index" function!
    public function _remap()
    {
        $assoc = $this->uri->uri_to_assoc( 4 );
        /* $assoc is now 
           array( "order"=>"title",
                  "sort"=>"desc",
                  "filter"=>"articletitle", 
                  "page"=>5); */
    }
}


I've run into this problem a ton of times and finally decided to try to solve it properly.

My solution involves a combo path/query string approach (it requires a solution like the one Stephen linked to).

URLs are formatted like so:

http://www.myapp.dev/controller/index/10?order_by=id+asc&status=open

These optional $_GET params can then be used as query conditions, and you can use as many as you want without screwing up CI's pagination offset.

By default, CodeIgniter's Pagination library doesn't support placing the offset before the end of the URI. The trick to getting CI to support this is to extend the pagination library like so: http://pastie.org/1393513

Then, in your controller, you can initialize pagination like so:

$config['url_format'] = site_url('controller/index/{offset}?'.http_build_query($params));
$config['total_rows'] = $this->model->count_rows();
$config['per_page'] = 5;
$this->pagination->initialize($config);

Note that no uri_segment is required, because the custom Pagination::initialize method detects it based on where {offset} falls in the url_format string.

Links that are built with $this->pagination->create_links() will insert the offset in the appropriate place, and preserve the tailing query string.


I don't like the fact that CodeIgniter destroys the query string. The query string is great for optional parameters. Trying to put optional parameters in URI segments and things start to get weird.

A URL like this seems a bit of a hack :

index.php/articles/index/order/title/sort/desc/filter/articletitle/page/5

For this reason I configure CodeIgniter to use a mixture of URI segments and query string. This answer shows you how you can achieve this.


It is a bit awkward that you can't use query strings by default. I've overcome this in my current project in a few areas by send the sort preference in a form post and then storing that preference in the user's session.


You could always do something like:

www.yourdomain.com/articles/order-title/sort-desc/filter-articletitle/page-5

by removing index.php with .htaccess. Then just explode on the "-" for each URI Segment.

$order = $this->uri->segment(2, 0);
$sort = $this->uri->segment(3, 0);
$filter = $this->uri->segment(4,0);
$page = $this->uri->segment(5, 0;

if(!empty($order)){
    $order = explode('-', $order);
} else {
    $order = 'defaultorder';
}

/** And so on for the rest of the URI segments **/

or even Remove the whole explode out of the equation and just do:

www.yourdomain.com/articles/title/desc/articletitle/5

$order = $this->uri->segment(2, 0);
$sort = $this->uri->segment(3, 0);
$filter = $this->uri->segment(4,0);
$page = $this->uri->segment(5, 0;

This is how most major business that use Code Igniter do their sorting and pagination.


Personally I'm a big fan or path/query string combo that Lou suggested, but I think I have a simpler method than his.

My solution puts the per page parameter in the query string along with your filtering parameters e.g.

http://mysite.com/admin/contacts?status=open&per_page=20

It works thanks to the page_query_string option of the pagination class. Here it is:

$query_string = some_function_to_get_your_filter_query_string_params();

$config['base_url'] = site_url("admin/contacts?". $query_string);
$config['total_rows'] = $total_rows;
$config['per_page'] = $per_page;
$config['page_query_string'] = TRUE;
$this->pagination->initialize($config);
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜