Welcome Guest, Not a member yet? Register   Sign In
HMVC the right way ?!
#21

Ok, maybe I have to clarify what my project is about to understand my questions.

I'm developing a custom cms for a client, which I'm almost to use for another client.
The idea is that a client can create a page and add 1 or more elements like html from a wysiwyg, image gallery, news list or other views of a certain module. 

I use HMVC because it give me the possibility to create sepperate modules which contain all code for one topic like news. So all views for front-end elements like news list and news item, and the backend maintanance application are there. Every module has his own db tables which are only used by that module.
Using the modules::run method gave me an easy way to get content from a certain module, and my pages controller would call modules::run for every element and put all collected data in the template of that page. 

Because I'm constantly reading that 'controllers calling controllers is bad' (practice), I wanted to get rid of modules::run and find another way. Because HMVC has the possibility to have libraries per module I thouht I could move the code to gather data from the database and create the needed HTML for my views.
So now my page controller can load the library from my news module and create my news list or news item without calling controllers from other controllers.

Narf will probably never touch HMVC with a ten foot pole, so I get that he wants to keep the libraries portable - without the use of models. But when using HMVC each module can contain it's own libraries, and my libraries use only module specific data. And because of HMVC they are portable in their own way, which gives me the possibility to copy and paste this module to the module folder of client nr 2 and by creating a new table in the db it can work right out of the box.

I would think this is a better way of doing than using modules::run, but if there's still a better way I am open for suggestions. I'm eager to so...

-Roger
Reply
#22

Roger - your example is exactly the situation where I consider calling models to be ok in libraries. Especially if models are treated as primarily a data access class that ensures that certain business rules are met. Then the library can take that data and reshape it however it needs (or even have it spit out HTML for you.) Since the library and model are part of a reusable module, and they area in the same module, it all works fine, as far as I'm concerned.

If you were creating a standalone library that was meant to be used outside of a module, then I would agree with Narf and say don't do it.

The biggest problem with the term "Library" in CodeIgniter is that it seems to have been EllisLab's term for any class that was not a controller or model. Depending on the context of those classes, there are different allowed uses, I think.
Reply
#23

(05-31-2015, 01:48 PM)RogerMore Wrote: Ok, maybe I have to clarify what my project is about to understand my questions.

I'm developing a custom cms for a client, which I'm almost to use for another client.
The idea is that a client can create a page and add 1 or more elements like html from a wysiwyg, image gallery, news list or other views of a certain module. 

I use HMVC because it give me the possibility to create sepperate modules which contain all code for one topic like news. So all views for front-end elements like news list and news item, and the backend maintanance application are there. Every module has his own db tables which are only used by that module.
Using the modules::run method gave me an easy way to get content from a certain module, and my pages controller would call modules::run for every element and put all collected data in the template of that page. 

Because I'm constantly reading that 'controllers calling controllers is bad' (practice), I wanted to get rid of modules::run and find another way. Because HMVC has the possibility to have libraries per module I thouht I could move the code to gather data from the database and create the needed HTML for my views.
So now my page controller can load the library from my news module and create my news list or news item without calling controllers from other controllers.

Narf will probably never touch HMVC with a ten foot pole, so I get that he wants to keep the libraries portable - without the use of models. But when using HMVC each module can contain it's own libraries, and my libraries use only module specific data. And because of HMVC they are portable in their own way, which gives me the possibility to copy and paste this module to the module folder of client nr 2 and by creating a new table in the db it can work right out of the box.

I would think this is a better way of doing than using modules::run, but if there's still a better way I am open for suggestions. I'm eager to so...

-Roger

Hi Roger,

Can you give an example of how this looks in views?
How do you handle using a template using this approach?

Thnaks
Reply
#24

(05-30-2015, 05:47 AM)Narf Wrote: Who said a library has to use a database? Or that it is a data access point at all?

You should be able to take a library, drop it in another application and work with it with no changes necessary. A model on the other hand is designed for a specific application. That's the only difference between the two.

I was going from the example code provided, which accessed a model to retrieve some data (which, in hindsight, could have been anywhere, but a database is often assumed when dealing with a model).

The biggest difference I see between libraries and models is that CI makes almost no assumptions about a library (except that there may be a config file with the same name which needs to be loaded and the result passed to the library's constructor), but assumes that a model will need access to CI itself (assuming you use CI_Model as a base) and that the database library may need to be loaded.

Because of these assumptions (made by the loader), and the somewhat-standard MVC roles in web applications, I prefer to avoid data access in libraries. However, in the event that a library needs to access data, I see no reason to shy away from loading a model to do so. Maybe we should inject the model or supply the data to the library's constructor, and those options should be considered when creating this type of interaction. We should also consider whether the functionality of the library in question should be part of a model rather than a library. The code, and how it's used, will usually pull you in one direction or the other.
Reply
#25

(06-01-2015, 08:13 AM)mwhitney Wrote:
(05-30-2015, 05:47 AM)Narf Wrote: Who said a library has to use a database? Or that it is a data access point at all?

You should be able to take a library, drop it in another application and work with it with no changes necessary. A model on the other hand is designed for a specific application. That's the only difference between the two.

I was going from the example code provided, which accessed a model to retrieve some data (which, in hindsight, could have been anywhere, but a database is often assumed when dealing with a model).

The biggest difference I see between libraries and models is that CI makes almost no assumptions about a library (except that there may be a config file with the same name which needs to be loaded and the result passed to the library's constructor), but assumes that a model will need access to CI itself (assuming you use CI_Model as a base) and that the database library may need to be loaded.

Because of these assumptions (made by the loader), and the somewhat-standard MVC roles in web applications, I prefer to avoid data access in libraries. However, in the event that a library needs to access data, I see no reason to shy away from loading a model to do so. Maybe we should inject the model or supply the data to the library's constructor, and those options should be considered when creating this type of interaction. We should also consider whether the functionality of the library in question should be part of a model rather than a library. The code, and how it's used, will usually pull you in one direction or the other.

Well, there's a significant difference between feeding data to a library and a library getting its data itself (by calling a model). The first case would be completely fine.
Reply
#26

And how does that work? 

Loading the news model from my pages controller and calling one of it's methods which calls a method of my news library..?! 
An example would be really helpfull to explain it to me.

Thanks in advance.

-Roger

@frocco, I didn't forget you. I'll post the answer to your question tonight or tomorrow.
Reply
#27

Thanks Roger.
Reply
#28

Hey Frocco,

My project isn't anywhere near finished and I'm ripping my code apart to take the modules::run out, so bear with me when I try to simplify my code.

A page in my cms has sections like header, left, middle, right, footer. Every section can hold 1 or more elements like a text or menu view. A page also has one template with the section predefined in it.

Supersimple page template:
Code:
<!DOCTYPE html>
<html>
<head>
   <style>
   </style>
</head>
<body>

   <div id="header">
   <?php if (isset($header)) echo $header; ?>
   </div>
   
   <div id="left">
   <?php if (isset($left)) echo $left; ?>
   </div>
   
   <div id="middle">
   <?php if (isset($middle)) echo $middle; ?>
   </div>
   
   <div id="right">
   <?php if (isset($right)) echo $right; ?>
   </div>
   
   <div id="footer">
   <?php if (isset($footer)) echo $footer; ?>
   </div>

</body>
</html>
I have one page controller which matches a slug to a page in the database and finds out which elements go with which sections. That data is reformatted into something that looks like:
Code:
Array
(
   [header] => Array
       (
           [10] => Array
               (
                   [module] => html
                   [view] => test
                   [settings] =>
               )

           [20] => Array
               (
                   [module] => flexslider
                   [view] => content
                   [settings] =>
               )

       )

)

Here you can see that there are 2 elements found for section header. In a foreach loop the output for the section is created:

PHP Code:
foreach ($elements as $section => $element) {
    foreach (
$element as $block) {
    
// here should be a check if a certain library is already loaded
    // ..
    
$this->load->library($block['module'].'/'.$block['module']); // this loads the html or flexslider library from the module with the same name
            
    
$html $this->$block['module']->$block['view']($block['settings']); // this call the method test from the html or the method content from the library flexslider which will create the output for the views.

    
if (!isset($sections[$section])) $sections[$section] = '';
    
$sections[$section] .= $html;
    }


After this all HTML for all sections is created and the array of $sections can be the data for the page template.

PHP Code:
$this->load->view("templates/{$pageTemplate}"$sections); 

And boom, your page with all the good stuff is put to screen...

Hope this helps.

-Roger
Reply
#29

(This post was last modified: 06-01-2015, 08:34 PM by no1youknowz.)

(05-29-2015, 09:50 AM)Narf Wrote: I disagree ... Libraries are supposed to be portable, not dependable on the application that uses them and you don't get that when a library uses a model.

(05-30-2015, 05:47 AM)Narf Wrote: You should be able to take a library, drop it in another application and work with it with no changes necessary. A model on the other hand is designed for a specific application. That's the only difference between the two.

Agreed on both these counts.

My 2c, HMVC is not the right way to code. Just look at all the trouble you guys are having just trying to make it work. Not only that, what about when you develop something and some noob jr dev comes along and tries to maintain it. Or how about the original dev leaves the company and someone like me has to support it.

I have my own code in Codeigniter that I can take from 1 project and plant into another. It's called libraries. Big Grin Things like auth, scrapers, cron, payment gateways. you name it, i have it and within minutes, I have something dropped in.
Reply
#30

(This post was last modified: 06-01-2015, 10:34 PM by RogerMore. Edit Reason: typo )

Ok. And here we are again. 

There isn't a lot of trouble I'm having to make it work. It was already working, but was searching for a way out of the controller calling controller thing.
The choice of HMVC is made, and this thread is not about whether to use it or not, it is about learning a way without modules::run.
I don't think projects aren't really harder to understand for a noob dev, because when you explain a module is like an application within CI they are fine. When a project as this is calling code from another module it maybe needs 15 minutes more explaining. I'm guessing a hardcore coder like you, no1youknowz, would have no problem whatsoever.

So you have your own code which you can put from 1 project to another which is called libraries. Who doesn't have that. One thing I'm missing though, is that your auth lib doesn't seem to need models and views for login/password forget screens or your payment gateway doesn't need at least some views for choosing which payment and so on. I hope that your login screen isn't popping out of your auth lib because I don't know if that would be a best practice...

I like things structured, so I like the idea of having a module folder with all models, view, controllers, libraries and so on. I honestly don't know how to do it another way, and as long the HMVC nay sayers only say nay and don't give a real answer to the questions or provide a similar solution I am good with HMVC.
Reply




Theme © iAndrew 2016 - Forum software by © MyBB