Use native CI passing URI Segments to Functions in Controllers?

edited September 2012 in Modules
In CI a uri of the form "site.com/tools/slug-one" would automatically map to the Tools Controller index function with the value "slug-one" passed as the first parameter.

How do we emulate that in the fuel environment?

What I want to do:
Have a single controller "Tools" which takes the slug value passed on the URL to use in calls against data models which passes the data to the view. The 'slug' value is part of an "Article" module in the Fuel CMS, so we need a dynamic way to call the controller functions and views.

I'd expect to be able to have a controller like this:

class Tools extends CI_Controller { function __construct() { parent::__construct(); } function index($subpage) { $this->load->model('articles_model'); $article = $this->articles_model->find_one_array(array('slug' => $subpage)); // handwaving ..... do stuff with the info in the data record $article $vars['article'] = $article; $this->load->module_library(FUEL_FOLDER, 'fuel_page'); $this->fuel_page->render(); } }

A request for "site.com/tools/slug-one" results in a 404

If I use $pages['tools/:any'] => array('view' => 'tools_article_display') then the controller is bypassed.

A request for "site.com/tools/" calls the index function (and results in an error message about a missing argument.)

Changing the function "index" to be an override of "_remap" gets a bit closer. The URI segment is passed to the function as an argument … but I get the following PHP error:

PHP Fatal error: Class 'Base_module_model' not found in /data/web/template2012/httpdocs/application/models/articles_model.php on line 3

Articles_modle.php begins like this:
class Articles_model extends Base_module_model { public $required = array('title','content','excerpt'); public $foreign_keys = array('fuel_navigation_id' => 'navigation_model'); public $linked_fields = array('slug' => 'title'); function __construct() { parent::__construct('articles'); } … <list_item, form_fields and various hooks here> }

Comments

  • edited 1:45PM
    You may need to have a route for tools/index/$1. IE explicitly set the method to index.

    Do you have this at the top of your model?

    <?php if ( ! defined('BASEPATH')) exit('No direct script access allowed'); require_once(FUEL_PATH.'models/base_module_model.php');

    I commonly call dynamic methods in controllers with:

    public function _remap() { $seg = $this->url->segment(_some_number_); $this->{$seg}(); }

    Wrap that in a switch or however you want to do it.

    Other things worth mentioning:
    Use find_one() instead of find_one_array() where possible. Especially if you have Base_module_record's defined.
    You appear to be on .9.3. There's a 1.0 branch if you want to check that out at: https://github.com/daylightstudio/FUEL-CMS/tree/1.0
  • edited 1:45PM
    Thanks Lance.

    I was missing the 'require_once' declaration. (so much for my 'mental note' about that)

    I'm afraid I don't understand where you're going with the _remap overload, but I was able to get my version of _remap to achieve my goal.

    I'm aware of version 1.0, but by my reading that is not yet stable. As this is our first move to FUEL CMS, I wanted to stick with a stable release. But I am keeping an eye on the 1.0 release for our next project.
  • edited 1:45PM
    No worries.

    The _remap was in answer to:

    "we need a dynamic way to call the controller functions"

    The _remap there will call a function of the same name as the $seg in your controller.

    1.0 is quite stable. I have six projects in various stages of development and release in 1.0. You're right though, 'official' line is it's in beta.
Sign In or Register to comment.