ExpressionEngine CMS
Open, Free, Amazing

Thread

This is an archived forum and the content is probably no longer relevant, but is provided here for posterity.

The active forums are here.

Views outside the CI directory structure?

October 19, 2008 11:21am

Subscribe [6]
  • #1 / Oct 19, 2008 11:21am

    escape

    20 posts

    I’ve been evaluating CI to determine if it can be used to replace a home grown MVC web application currently being used on our website. I see great potential for expanding the application’s functionality using CI however I’ve run into a situation that is causing great difficulty. Specifically I would like create views without making major modifications to the design layout of the site.

    For simplicity consider a simple html form that already exists on the website. Now if I wished to use CI to handle all aspects of validation and processing the form submittal I would need to create a view to do so. This would entail moving the webpage containing the form to the view directory, re-establishing any references to external resources (.js, css, images, etc.) and of course implementing the necessary CI constructs to handle the form. The problem I’m facing with this approach is that it makes it exceedingly difficult to leverage the design layout of an existing website. Or for that matter if the website design changes or the application needs to be replicated elsewhere the view must be re-created.

    I’ve seen several posts and strategies suggesting ways incorporate external assets into CI views by placing js, css, images, etc., in a directory outside the CI structure, then referencing these assets in a view via base_url() (or similar convention). I have yet found a way to reference html pages in a similar fashion.

    Re-visiting the above simple form example using the current home grown MVC framework, I can simply reference the web page containing the form and replace the actual form elements with a parsing pseudo-variable (or array key <?php echo $my_form;?>). With this approach all I have to is make simple html edits to the reference web page replacing the form with the parsing pseudo-variable. Since the form web page remains in the directory where it was created I don’t have to move it or re-establish any asset references.

    Is it possible to make external references (outside the CI directory structure) to view templates? Or is there another approach that could be used.

    Thanks,
    Chris

  • #2 / Oct 19, 2008 12:48pm

    manilodisan

    223 posts

    I would write my own function that loads the views from another folder, outside CI’s installation folder, however, I’m not sure if it works though….

    //helper
    define ( 'VIEWS_LOCATION', '/var/www/public_html/views/' );
    
    function load_external_view ( $data, $view )
    {
        return $this->load->view ( $data, VIEWS_LOCATION . $view );
    }
    
    
    //controller
    $data = array ();
    return load_external_view ( $data, 'my_view_filename' );
  • #3 / Oct 19, 2008 12:55pm

    Bramme

    574 posts

    I think you’d rather need a load->external_view() function, the only difference being that the external_view() function will look for html files outside the CI view directory.

  • #4 / Oct 20, 2008 10:37am

    escape

    20 posts

    I tried several variations of directing $this->load->view to an external file and got different results, none of which seemed to solve the problem.

    1 - by creating a reference to a parent directory.
    $this->load->view(’../../../public/form.htm’, ‘’ , true)
    From the view directory I’ve created a public directory at the same level as the CI system directory. With a parent reference (../../../public/form.hmt) CI finds and loads the remote view however all assets (i.e., images, css, etc.) within the form.htm file not maintained. If I edit href assets within form.htm with ../public/ the references are maintained. This is not a solution just an observation.

    2 - creating a path via PHP
    $this->load->view(dirname(dirname(dirname(dirname(__FILE__)))) . ‘/public/form.htm’, ‘’ , true)
    Although this path definition points to the same location in the directory structure as ‘../../../public/form.htm’, CI throws the error: Unable to load the requested file.

    Since assets within form.htm are relatively referenced just defining a path to the file may not be sufficient. Is it possible to move the controller outside the controller directory?

  • #5 / Oct 20, 2008 10:43am

    Bramme

    574 posts

    Just off the top off my head: have you tried a symlink? That way, you wouldn’t have to mess around with CI’s methods.

  • #6 / Oct 27, 2008 12:25pm

    escape

    20 posts

    Problem solved with a recommendation from Ishmael, who’s deep understanding of CI is revealed in this post
    http://ellislab.com/forums/viewthread/73545/

    By creating a My_loader library you are able to specify, in a controller, an as needed reference to an external view directory like the CI root in example below:

    - CI
    —index.php
    —system
      —- application
        ——views
    - form_assets_dir
    - form.htm
    - CI_front_controller (my_index.php)

    In this example form.htm represents an existing web page design in the same directory as the CI install. However setting a view reference to this directory alone will not maintain relative references to assets the form uses. This is because all references to the form’s assets will be relative to the CI front controller index.php, which is in the CI root directory.

    By moving CI’s front controller to the same level as form.htm, my_index.php will access the form and maintain relative references to any assets in the form. The only modification to index.php is setting the system folder path ($system_folder = “CI/system”).

    Using this approach I can create clones of index.php then define a view directory in the default controller.

    Although this approach seems to work it would be nice if making portable CI front controllers were added to the MVC framework.

  • #7 / Nov 03, 2008 3:39pm

    escape

    20 posts

    Further investigation of this problem has revealed this is a very limited solution. If the controller calls a function (say, my_function) then the url will look something like this: my_index.php/my_function. When this happens links to all assets in form.htm (i.e., css, images, etc.) will no longer be valid because now it appears the page should reside in a subdirectory called my_function.

    So for only the simplest cases trying to integrate CI into an existing web site design is going to cause a lot of html refactoring. Having to change asset references to accomodate CI’s view path doesn’t seem to be a very robust solution. It would be preferrable to change CI’s view path to accomodate an existing html design, but apparently that isn’t entirely possible.

  • #8 / Apr 21, 2009 11:21am

    dxrsm

    3 posts

    You could extend Loader as MY_Loader, and reset the view path in the constructor like this:

    class MY_Loader extends CI_Loader{
           
        function MY_Loader(){
            parent::CI_Loader();        
    
            $this->_ci_view_path = "/my/views/folder/";
            
        }

    You can then load your views as usual.
    The benefit from that approach is that you can have your view files bundled with your assets.

  • #9 / Apr 21, 2009 11:38am

    Phil Sturgeon

    2889 posts

    The reason a full path will not work is that (if I remember correctly) CI uses realpath() to create the full path. So it will follow symlinks but either way it will not to be relative and not absolute.

  • #10 / Dec 18, 2011 3:24pm

    linnovision

    5 posts

    Wow this is a really old post . . .  and yet i went about in circles trying to find a solution to this problem.

    after a lot of trial and errors. this is what works for me. Although not very impressive. it takes care of the root directory issue pointed out earlier by @escape

    ok here is what ive done. please correct me if there are better ways to do this.

    * i copy all my view files into the views directory
    * copy my resources into the front controller directory. ie. FCPATH
    * add a <base> tag to the <head> tag of all html files. ( if the views are used as “includes” this really helps.)
    Eg. of base tag

    <head>
            <base href="{root}" />
    </head>

    * us the below _remap() method in a universal controller

    public function _remap( $method, $params = array() ) {
    
    
                    // Check if method exists in current class
                    // if success --> call method
                    // if fail --> check for view file
                    if( method_exists( $this, $method ) ) {
    
                            $params = array( current_url() );
                            call_user_func_array( array( $this, $method ), $params );
    
                    }
                    else {
    
                            // set view as designated index file, if no uri provided
                            $viewName = ( $method == "index" ) ? $this->index : uri_string();
    
                            $viewDir = APPPATH.'views/';
    
                            // check if given viewName is a directory, if yes --> use index file of directory
                            $viewFile = ( is_dir( $viewDir . $viewName ) ) ? $viewName .'/' . $this->index : $viewName;
    
                            //
                            if( file_exists( $viewDir . $viewFile ) ) {
    
                                    $data = array( 'root' => site_url() );
    
                                    // parses root value to be used as base for all resource files
                                    $this->parser->parse( $viewFile, $data );
    
                            }
                            else {
    
                                    // this sets status as 404 and loads custom 404 page
                                    $this->page_not_found( current_url() );
                            }
    
                    }
    
            }

    * Now this {root} can be parsed using the parser library. where

    root = site_url()

    This way the resources will always use the root directory provided in the base tag.

    and the structure of the existing url system will be maintained. without much changes to html.

    this method is not good if the resources are not arranged in neat folders, for then you could have a whole list of images, js, css files in the root folder which can get really anoying.

  • #11 / Dec 19, 2011 7:28am

    Phil Sturgeon

    2889 posts

    This certainly is an old post!

    Since this was written we now have Application Packages, which are a feature that creates new areas like the application folder. You can have a shared resources area that has shared views, models, libraries, etc.

    Read about it more in the Loader documentation.

.(JavaScript must be enabled to view this email address)

ExpressionEngine News!

#eecms, #events, #releases