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.

Nested MVC

January 31, 2008 9:08pm

Subscribe [14]
  • #46 / Feb 15, 2008 5:39am

    Edemilson Lima

    241 posts

    I can’t really see the point of this biz_loader, everything in it can be achieved with libraries or plugins.

    The main objective is to keep things more organized, not only in the folders, but also in the code. I pointed out about this some posts before:

    The “application/helper” folder is ideal for extending/replacing core helpers (since 1.6.0) and to put my sporadic functions, like my own string/date format/validate functions or things like that.

    The “application/libraries” folder is ideal for extending/replacing core libraries and to put my proprietary libraries, with things like my own template parser, my own session management, file management, etc.

    May I could use the “application/plugins” folder to put my application modules/partials, but the name “plugins” suggests me that such folder is for third part applications, like for example, a plug-in to import/export data from another web site.

    One option could be use the “application/models” folder to put my modules/partials as models, but I don’t think this is a good pratice too. My modules/partials are more like controllers than models. They will have their own models and will load their own views.

    In my opinion, to create helpers, libraries or plug-ins and use them as my application modules/partials are not the best pratice, because helpers/libraries/plug-ins are things related to the low level of my application, which rarely deals with my application logic.

  • #47 / Feb 15, 2008 5:56am

    wiredesignz

    2882 posts

    It appears to me that plugins are equal to modules in terms of how they are implimented, I have never seen anyone talk about using a third party plugin. Maybe we as developers are the third party?

    If the plugins directory was called modules, would you feel different?

    The CI loader also has the ability to load scripts, which is simply include(), could that directory be changed to modules, would that make it any different?

    All biz_loader does is add a modules directory to the loading structure, it doesn’t change any CI functionality.

  • #48 / Feb 15, 2008 6:03am

    wiredesignz

    2882 posts

    Maybe we should ask Ellislab to change the plugins directory name to modules. it would serve the same purpose.

  • #49 / Feb 15, 2008 8:26am

    BizComputing

    60 posts

    wiredesignz -> I can’t really see the point of this biz_loader, everything in it can be achieved with libraries or plugins.

    Wired, you don’t need to see the point of biz_loader, I wrote it for me, for my projects to meet my needs.  I specified in this thread that it may not be of any use to anyone else.  If it’s of no use to you, then fine, I warned you.  I only posted it because it was asked for, and, seems to have met the need of at least 1 other member.

    And you are completely correct, everything I am doing in biz_loader can be done already in CI.  But the same can be said about Matchbox, yet, there are many developers who enjoy the additional organization.

    I added 2 features, 1 the ability to load a class without instantiation.  Pah, I could have just put in a require/include, or gone with load_class in Common, but I weighed those and found them lacking ( in my own mind ).  require/include is not the CI way, and I don’t benefit from knowing what is already loaded via CI, so, I lose some ability when I use require/include, the same is true with load_class in Common.  So, I think I have added a feature to CI.  Small, insignificant.

    The 2nd feature I added was modules.  And I’ve stated many, many times already, it’s a library, so, yes, CI can do this already. But, can CI allow me to divide up my libraries into other folders for organization?  And no, my use of modules are not plugins, a plugin is a function not a class.  And even though my modules have the ability to load and not instantiate, I’m not using that ability for modules, only for libraries.

    As for my wanting to load libraries without instantiation, some of that is due to bringing over libraries that don’t meet the CI interface.  Some of these are large enough to not want to rewrite the interface so it is CI like.  So rather than rewrite, I want to load it, then instantiate it myself with new the PHP old fashioned way.  Additionally I have libraries that need multiple local instances.

    So, sorry there is no use in my lib for you, I warned everyone.  But please, don’t bash what I did just because it doesn’t suit your needs nor does it provide functionality that you are looking for.  You continue with that attitude about ppl’s submissions and the community will fold in on itself and stop sharing.

  • #50 / Feb 15, 2008 8:28am

    Edemilson Lima

    241 posts

    It appears to me that plugins are equal to modules in terms of how they are implemented, I have never seen anyone talk about using a third party plugin. Maybe we as developers are the third party? If the plugins directory was called modules, would you feel different? The CI loader also has the ability to load scripts, which is simply include(), could that directory be changed to modules, would that make it any different?

    I don’t know exactly how plugins work inside, but if it is as you said, so the name could be modules or even partials. But I think that real third party plugins are more like these simple include() scripts. What I feel about plugins, is they are an interface to exchange data between my web site and another services. Or they are third party things that I could add to my application without change any line of code on it. Am I wrong?

    All biz_loader does is add a modules directory to the loading structure, it doesn’t change any CI functionality.

    I agree. But this depends on how you use it. For example, I would like to do something like this:

    // subpage controler:
    class Subpage extends Controller {
        
        function index() {
            $this->load->view('subpage_view');
        }
        
    }
    
    // subpage view:
    <div id="left"><?=$this->load->module('leftside')?></div>
    <div id="center"><?=$this->load->module('centerpage')?></div>
    <div id="right"><?=$this->load->module('rightside')?></div>
    
    
    // leftside module:
    class Leftside extends Modules {
        
        function index() {
            $this->load->model('categories_model','categories');
            $data['categories']=$this->categories->get_list();
            $this->load->view('categories_view',$data);
        }
    
    }
    
    // centerpage module:
    class Centerpage extends Modules {
        
        function index() {
            $this->load->view('center_view');
        }
    
    }
    
    // center_view:
    <div id="offers"><?=$this->load->module('offers')?></div>
    <div id="products"><?=$this->load->module('products')?></div>
    
    // offers module:
    class Offers extends Modules {
    
        function index() {
            $this->load->model('products_model','products');
            $data['offers']=$this->products->get_offers();
            $this->load->view('offers_view',$data);
        }
    
    }
    
    // products module:
    class Products extends Modules {
    
        function index() {
            $this->load->model('products_model','products');
            $data['products']=$this->products->get_list();
            $this->load->view('products_view',$data);
        }
    
    }

    Basicly it is the same idea of Rick Jolly of a view-centric approach, but instead of using a helper to load a library as a module, I want to load a module from its own folder. Could I use plugins instead? Maybe, but I don’t want to mix my partials with my plugins. They are completely different things.

    In fact, I don’t know if biz_Loader do exactly what I want. I will try it because I find it much better than use a library or a plugin to do this. But what I really like to have was something already built into the framework, like a real HMVC, where I could load subcontrollers within controllers. It must be something that eliminate the task of pre-build all my partials in every controler and every function, to render the whole page.

    To make it simple and clear, what I really want in CodeIgniter was the ability to load a controller from a view and it works fine. Just like that. Why is such thing is so hard to implement into CI, if we consider that a controller is not that much different of a library? What is the main problem?

  • #51 / Feb 15, 2008 10:03am

    wiredesignz

    2882 posts

    @BIZ: I’m not bashing. I see why you have done this. My point is that Ci already has the same functionality under a different name.

    Matchbox however is totally different, It allows you to have modules containing complete MVC applications.

  • #52 / Feb 15, 2008 10:07am

    BizComputing

    60 posts

    I could be completely off base here so ignore if I am.

    It seems as I’ve dug in and studied the CI infrastructure that the controller loaded in response to the provided URI is central to everything.  Everything that loads, loads against that controller.  When you get_instance(), you are getting the reference to that controller.  So it’s not that there is a problem in loading multiple controllers so much as it is of CI’s design.  If a controller is central, then how do other controllers (which are coded to be the center of the request) interact with the infrastructure?

    CI was not designed to be HMVC.  Even though I desire HMVC, I would not want the CI team ripping thru CI to support this unless it was trivial (which it does not appear on the surface to be a trivial design change).  CI is designed to be lightweight and as get-out-of-your-way as possible IMHO and the more complicated you make the infrastructure, the less lightweight it becomes.

    With what you appear to want, my module and loader would only be a starting point.  It seems to me that you need to come up with a module that on instantiation takes off with it’s piece of the pie so that your controller or view( I say view since it looks like you are loading your modules from your view ) only need to instantiate your module and that put’s your module on auto pilot.  Seems to me you could do that just by changing your index methods in your modules to the constructor, just make sure that if you are basing your module design on a superclass similar to my module superclass that you first call the superclass constructor.

    off the top of my head, maybe these changes might work for you:

    // subpage controler:
    class Subpage extends Controller {
        
        function index() {
            $this->load->view('subpage_view');
        }
        
    }
    
    // subpage view:
    <div id="left"><?=$this->load->module('leftside')?></div>
    <div id="center"><?=$this->load->module('centerpage')?></div>
    <div id="right"><?=$this->load->module('rightside')?></div>
    
    
    // leftside module:
    class Leftside extends Modules {
        
        function Leftside() {
            parent::Modules(); // creates reference to real controller
            $this->ci->load->model('categories_model','categories');
            $data['categories']=$this->ci->categories->get_list();
            $this->ci->load->view('categories_view',$data);
        }
    
    }
    
    // centerpage module:
    class Centerpage extends Modules {
        
        function Centerpage() {
            parent::Modules();
            $this->ci->load->view('center_view');
        }
    
    }
    
    // center_view:
    <div id="offers"><?=$this->ci->load->module('offers')?></div>
    <div id="products"><?=$this->ci->load->module('products')?></div>
    
    // offers module:
    class Offers extends Modules {
    
        function Offers() {
            parent::Modules();
            $this->ci->load->model('products_model','products');
            $data['offers']=$this->ci->products->get_offers();
            $this->ci->load->view('offers_view',$data);
        }
    
    }
    
    // products module:
    class Products extends Modules {
    
        function Products() {
            parent::Modules();
            $this->ci->load->model('products_model','products');
            $data['products']=$this->ci->products->get_list();
            $this->ci->load->view('products_view',$data);
        }
    
    }
  • #53 / Feb 15, 2008 10:20am

    BizComputing

    60 posts

    Wired: Matchbox however is totally different, It allows you to have modules containing complete MVC applications.

    I disagree, Matchbox simply reorganizes your code so that you can package your M with your V with your C, it does not provide a simple infrastructure for having HMVC.

    I am not attempting to downplay Matchboxes contribution to the CI community, in fact, I intend to look at Matchbox if not for the implementation, then for the ideas.

    And your insistence that I have brought nothing to the table but re-invented what is already in CI seems very much to be bashing to me.  I am using a superset of what I presented in an actual application.  There are other programmers involved in this application.  They agree that the simplicity of my infrastructure has led to cleaner more CI like application design while allowing for a simple to implement HMVC simulation.  I can take one of my modules and plug it into another controller with a few lines of code and voila I gain the whole modules control code, model code, and view code within the main MVC.

    So once again I say, it may not be of use to you, but please, don’t downplay what I have done just because it doesn’t make sense to you or provide you any benefit.

  • #54 / Feb 15, 2008 10:29am

    wiredesignz

    2882 posts

    I agree with the flexibility to have HMVC style sub-controllers when needed, My issue is NOT with what you have acheived. I disagree with need to constantly hack the core to acheive this. What if someone wants Matchbox functionality together with your HVMC loader? They’re pretty much screwed.

    To that end I have posted a poll in Feature Requests.

  • #55 / Feb 15, 2008 11:44am

    codex

    332 posts

    I’m slightly confused about the difference between Matchbox and bizloader. I *think* I know what the difference is, I’m not sure, but is it so that Matchbox modules are only accessible via the URL, whereas bizloader modules are accessible via controllers?

  • #56 / Feb 15, 2008 12:16pm

    BizComputing

    60 posts

    I’m not versed in Matchbox enough to know for certain, but Matchbox seems to meet the need of code organization.  It does not change that each request is serviced by a controller which in turn can load as many views and/or controllers as it needs to do it’s job.

    bizloader and the module class that follows it allows for what is called HMVC.  It is simulating multiple controllers executing per request.  The CI infrastructure as it exists will only allow 1 controller to execute per request.  HMVC is saying, rather than have my request handled by 1 controller, allow parts of my request to be serviced by sub-controllers.

    bizloader only simplifies and organizes my SIMULATED HMVC.  I say simulated because my module(sub controller) is really only a library, a libary that loads it’s own model(s) and view(s).  I currently need this feature because I have a client management screen that also manages the address(s) of the client and manages the contact_method(s) of the client and manages the people at that client.  I also have a screen that manages contacts, these contacts also have addresses, contact_methods, and people associated with the contact.  The original application that has these screens was written in pure PHP with no assistance from any framework except a home-grown solution.  The addresses were coded as it’s own module, the contact_methods was coded as it’s own module, the people was coded as it’s own module.  Then with a few lines of code, these modules can be called from the client screen and also called from the contact screen.

    There is no need to use biz_loader or the example module following it.  It was provided simply because it was asked for and to serve as an example of something that is working in the real world.  biz_loader provides for 2 features above what the standard loader provides.  First it provides for loading a library without that library being instantiated.  This feature was added not for my simulated HMVC work but because I have libraries that I am porting that do not conform to the CI way of things.  The are classes and I wanted to use the load->library to be consistent with CI libraries but I need to instantiate them seperately.  I could have loaded without instantiation by treating these as a helper, or as a plugin, or by using the Common load_class function or by simply using PHP include/require.  I personally didn’t like any of those methods, I wanted to make my libraries act as closely to CI libraries as possible without haveing to rewrite my library interfaces.

    The second major feature of biz_loader is the ability to load a module.  Once again, there is no need for this functionality since my modules are simply libraries.  I implemented it as an extra loader to help organize my code MY WAY so that I could take these special libraries and move them into a different folder than the common libraries so that I organizationally know that these libraries are functioning in a special way.  Additionally, my modules all inherit from a common ancestor class.  This ancestor class is also simply a library and therefore could have been loaded as such.  But, loading it would have instantiated it which would have been a waste of resources because I don’t need an instance of superclass, the superclass is only there to provide common structure and functionality to all my “modules”.  So I’m back to wanting to load a library without instantiation so that the superclass definition would be in memory for when I instantiate my subclasses.  All of this DID NOT REQUIRE extensions to the loader.  I extended the loader for convenience and structure.

  • #57 / Feb 15, 2008 12:43pm

    Edemilson Lima

    241 posts

    If a controller is central, then how do other controllers (which are coded to be the center of the request) interact with the infrastructure?

    Well, it is a hard question. I will try to explain my opinion. Sorry if my english is not that good. Sometimes I can’t explain exactly what I’m thinking… But thank you for your patience and for your valuable help! 😊

    The modules could be exactly like controlers in their structure and also be in the same folders the controllers are. But, the modules won’t need to be called directly by the URI. They could be like “private classes” (ie private controllers), maybe their names can start with a trailling underscore too, I don’t know. Modules should be designed to be loaded directly by views or by controllers, injecting them into views.

    When a view is rendered, the module index() function should always be executed and it will return the result to the view it belongs. It can also have its own models and subviews, and these subviews will can load their submodules, making the whole thing hierarchyly.

    The main problem here, I think, is how to control the flow to execute some desired function inside any desired module… Normally this thing is up to the developer to resolve, not to the framework. It will becomes even more complicated if we have the same functions names in different loaded modules. I really don’t know how an HMVC solve this issue.

    Imagine an URI like this:

    <a href="http://www.mysite.com/&#91folder/&#93controller/&#91module/&#91submodule/&#93&#93function/parameter1&#91/parameter2&#93">http://www.mysite.com/[folder/]controller/[module/[submodule/]]function/parameter1[/parameter2&#93</a>;

    I can’t figure out how the engine could manage this. It must load only the controller and pass to it what function will be executed, in what module. And also, if I call a function of my controller that have the same name of a module, how the engine will know what thing is to be called?

    So, forget everything I have said until now. I am always in favor of simplicity.

    I just need to load my modules from my views and execute them. No need to more than that. Anything more special I can do in my controllers, which was designed to this purpose. The modules are just partials, that I want to reuse their code everytime I want in my application.

    For example, imagine a page where I load the same module twice. It must be loaded only once, but it need to be executed two times. When I load it, I can pass parameters to it, so each execution of the same module can deal with different data.

    It seems to me that you need to come up with a module that on instantiation takes off with it’s piece of the pie so that your controller or view ( I say view since it looks like you are loading your modules from your view ) only need to instantiate your module and that put’s your module on auto pilot.

    Exactly! The idea is to load a module and it be independently from the rest, but with full access to the CI resources, like controllers have.

    Seems to me you could do that just by changing your index methods in your modules to the constructor, just make sure that if you are basing your module design on a superclass similar to my module superclass that you first call the superclass constructor.

    Hmmm… It is more clear for me now. But isn’t in some way possible to modules extend the controller instead of a module superclass? Is there any way to use $this->load->model() and $this->load->view() instead of $this->ci->load->model() and $this->ci->load->view()? I would like to have something more standard, working like anything else in CI.

  • #58 / Feb 15, 2008 12:53pm

    BizComputing

    60 posts

    Hmmm… It is more clear for me now. But isn’t in some way possible to modules extend the controller instead of a module superclass? Is there any way to use $this->load->model() and $this->load->view() instead of $this->ci->load->model() and $this->ci->load->view()? I would like to have something more standard, working like anything else in CI.

    You can’t have your “subcontrollers” extend the controller because the controller initializes certain aspects of the framework like the instance returned by get_instance().  If I’m correct, get_instance would then return the last subcontroller loaded rather than return the real controller.

    As for eliminating the ci in the calling chain, I’m sure it’s possible, I imagine doing just what many of the CI core classes do, and that would be to copy the loader instance from the real controller to a load var in your module.  I believe that the loader would still load the models and views onto the real controller.  All of this is possible with further tweaking of the loader class.  I’m simple minded though so I would rather keep the mods to the loader to a minimum.  I rather like having the ci in the calling chain though because it reminds me that I am NOT in a controller but one of my pseudo controllers.

  • #59 / Feb 15, 2008 1:28pm

    Edemilson Lima

    241 posts

    You can’t have your “subcontrollers” extend the controller because the controller initializes certain aspects of the framework like the instance returned by get_instance().  If I’m correct, get_instance would then return the last subcontroller loaded rather than return the real controller.

    Also, if I name a function in my module with the same name of a function in my controller, will they collide or not?

    All of this is possible with further tweaking of the loader class.  I’m simple minded though so I would rather keep the mods to the loader to a minimum.

    People say that this can be done using libraries. But why libraries doesn’t need the “ci” in the chain too?

    I rather like having the ci in the calling chain though because it reminds me that I am NOT in a controller but one of my pseudo controllers.

    To not make confusion between my models, views and controllers, I’m naming models and views with “_model” and “_view” sufixes. I don’t mind to sufix my modules too. And also, if they be in another folder, I just take a look to know where I am. 😊

  • #60 / Feb 15, 2008 2:43pm

    Sam Dark

    242 posts

    I’ve implemented what you are talking about here a week ago with a helper as a loader so I can use modules as partials calling them with some additional parameters.

    First, as was said before I’m using CI instance in my module so everything loaded is loaded into current controller. I’m naming module classes postfixed like Edemilson Lima said so for now there are no naming conflicts appeared.

    When using my helper within views I can use native $CI->load->view(‘myview’, $param) to render my partial so it seems very close to CI’s native way of working with controllers.

    I’ve started another topic recently where I’ve said I want calling another controllers.

    Now after reading this topic is seems separate directory for partial modules is better because of separating actual controllers from partial controllers.

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

ExpressionEngine News!

#eecms, #events, #releases