Love Fuel?    Donate

FuelPHP Forums

Ask your question about FuelPHP in the appropriate forum, or help others by answering their questions.
Same view names in different modules
  • Is there a way to use same view names in different modules? As I can see now views cached by name in find_file() method. I develop HMVC application and want to have widget.php view in publications module and news module, but when I call it from two modules I have last called widget 2 times:(
  • Have you tried to put your view in APP/views/ directory?
  • Charlie Black wrote on 02/05/11 6:47 pm:
    Have you tried to put your view in APP/views/ directory?
    No, its modules views. I'm writing CMS on FUEL and I need in every module widget.php view for auto render widgets;)
  • As long as you put the namespace of the module at the top of the view, you can call views HMVC-like. I'm 99% sure that's how you do it. I'm on my iPhone just now, when I'm on my laptop I'll check and paste the code (I've achieved this several times in a project management app I'm building on fuel)
  • Ben Corlett wrote on 02/07/11 10:22 am:
    As long as you put the namespace of the module at the top of the view, you can call views HMVC-like. I'm 99% sure that's how you do it. I'm on my iPhone just now, when I'm on my laptop I'll check and paste the code (I've achieved this several times in a project management app I'm building on fuel)

    Ben it doesn't work. May be because I use develop branch of Fuel?
  • Here is my code: classes/base.php
    class Base extends Controller_Template {
    
     public function before()
     {
      parent::before();
      
      //Initalize session
      //$session = Session::instance();
    
      Asset::css(array('main.css'), array(), 'css', false);
      Asset::js(array('jquery.min.js'), array(), 'js', false);
      
      $this->template->login_error = null;
    
      if (\Auth::check())
      {
       $user = Auth::instance()->get_user_id();
       $this->user_id = $user[1];
    
       $this->template->logged_in = true;
      }
      else
      {
       $this->template->logged_in = false;
      }
      
      //Widgets init
      \Fuel::add_module('ideology', true);
      \Fuel::add_module('publications', true);
     }
    
     public function action_404()
     {
      // Set a HTTP 404 output header
      Output::$status = 404;
      $this->template->title = '404. Page not found.';
      $this->template->content = View::factory('welcome/404');
     }
    }
    

    Part of: views/template.php
     ...
     <div id="sidebar">
      <?php echo @\Ideology\Controller_Ideology::widget(); ?>
      <?php echo @\Publications\Controller_Publications::widget(); ?>
     </div>
     ...
    

    app/modules/publications/classes/controller/publications.php
    namespace Publications;
    
    class Controller_Publications extends \Base {
     public function before()
     {
      parent::before();
     }
     public function action_index()
      {
      $this->template->title = 'Publications';
      $this->template->content = \View::factory('publications_index');
     }
     public static function widget()
      {
       $data = array();
       return \View::factory('widget', $data);
     }
    }
    
  • where are the views located? (the widget view for Controller_Publications for example)? Sorry if i don't reply straight away - it's the middle of the night here in Australia :)
    EDIT: forget what i just said - i just read what you said haha. i'll have a play around in the morning
  • what about if you did something along the lines of the following:
    // Views/template.php
    <?php echo Request::factory('publications/widget')->execute()->output() ?>
    
    // Then in publications/classes/controllers/publications.php
    public function action_widget()
    {
        $data = array();
        $this->response = $view->factory('widget', $data);
    }
    
    // I believe the stuffup is caused by something in the after() function of the controller
    // and that's why it's getting the wrong view. especially because your'e putting a static
    // function in a controller, which means it's not really part of that object but more a 
    // virtual 'self'.
    //
    // try maybe making a file under publications/classes called publications (not under controllers).
    // have the static function there, which returns the HMVC call (the Request::factory()->execute()->output();
    

    tell me how that goes. it's a much better way of approaching it. as far as loading views explicitely from other modules, i might revert from my last couple of comments, not too sure you can do it. the parameter is just a location for the fine_file() function to find a view - no room for namespacing. i'll put something on github as a feature request, but i think that doing proper HMVC requests is the best approach to it (Request::factory()). the hierarchy of views is as such: say i have a module, publications. in a function i want to render the view 'someview'. it'll look for views in the module first, then the app directory, then the packages directory, then the core directory. it'll keep falling back if it can't find one (this comes out of kohana's cascading file system concept - great idea). but as far as namespacing goes, it's not really possible (with the current structure) to call a namespace when trying to find a file - as the namespace has more to do with the runtime than the file system. anyway - let me know how you go with the Request::factory() method. also, one more tip - rename base.php. move it under controllers/ and call it template.php. then all of your controlelrs have:
    class Foo extends \Controller_Template
    

    (make sure you've added your controller template to your bootstrap.php file, and in it add the following:
    class Controller_Template extends Fuel\Core\Controller_Template
    {
       public function before()
       { 
            // blah
       }
    }
    
  • Tip: put the following in your controller_template.php file (or base.php if you choose to keep it).
    /**
     * Set Template
     * 
     * Override a template after it is defined
     * (used for loading different templates
     * for different user agents)
     * 
     * @param string name of the template
     * @return  Controller_Template
     */
    protected function _set_template($template, $refresh = false)
    {
     $this->template = \View::factory($template);
     
     return $this;
    }
    

    it's just a function so that you can set a new template in a function for any reason.
    I used it on an app that had different user agents (eg iphone - although the following example
    isn't about an iphone :) ):
    // classes/controllers/somecontroller.php
    public function action_test()
    {
       if ($foo == $bar)
       {
           $this->_set_template('sometemplate/default');
       }
    }
    
  • Thanks Ben, I will try to play with code which you suggested. I found reason why my code doesn't work as I expected: fuel/core/classses/view.php:
    ...
     public function set_filename($file)
     {
      if (($path = [b]\Fuel::find_file&#40;'views', $file&#41;)[/b] === false)
      {
       throw new \View_Exception('The requested view could not be found: '.\Fuel::clean_path($file));
      }
    
      // Store the file path locally
      $this->_file = $path;
    
      return $this;
     }
     ...
    

    fuel/core/classses/fuel.php:
    ...
     public static function find_file&#40;$directory, $file, $ext = '.php', $multiple = false&#41;
     {
      $path = $directory.DS.strtolower($file).$ext;
    
      [b]if (static::$path_cache !== null && array_key_exists($path, static::$path_cache))
      {
       return static::$path_cache[$path];
      }[/b]
    
      $paths = static::$_paths;
      // get the paths of the active request, and search them first
      if ($active = \Request::active())
      {
       $paths = array_merge($active->paths, $paths);
      }
    
      $found = $multiple ? array() : false;
      foreach ($paths as $dir)
      {
       $file_path = $dir.$path;
       if (is_file&#40;$file_path&#41;)
       {
        if ( ! $multiple)
        {
         $found = $file_path;
         break;
        }
    
        $found[] = $file_path;
       }
      }
    
      [b]static::$path_cache[$path] = $found;[/b]
      static::$paths_changed = true;
    
      return $found;
     }
     ...
    

    I think issue in this line static::$path_cache[$path] = $found; it cached for 1st module and second module get cached view path.
    Because when I debugged my 2 modules $path was 'views/widget' for module publications and module ideology. PS: views for modules located at app/modules/[module_name]/views/
  • Ben, I tried your approach (HMVC) from post # 7, but widgets returned with view of module publications, which loaded first. I think there is bug in core/classes/view.php: I have 2 modules: publications and ideology, I have view widget.php for each module:
    app/modules/publications/views/widget.php
    app/modules/ideology/views/widget.php
    When I use HMVC in views/template.php code:
    <?php
    echo \Request::factory('publications/widget')->execute()->output();
    echo \Request::factory('ideology/widget')->execute()->output();
    ?> widget publications and widget ideology outputted with view app/modules/publications/views/widget.php. I think because of caching in fuel/core/classes/fuel.php in method find_file() I posted issue to bugtracker: https://github.com/fuel/fuel/issues/#issue/184
  • Today bug was fixed:)
    Big thanks to Harro Verton!
  • You're welcome! :)

Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

In this Discussion