Welcome Guest, Not a member yet? Register   Sign In
Multiple controllers per page + Multiple instances of the same model
#1

Hi!

I found CodeIgniter yesterday, and thought that it was quite awesome - So I'd like to jump right in and create that webapp idea I've had for a while.

Now, this post contains two (Actually, three - no, four) questions - I didn't find a real answer to those while searching on google, so I hope that I'm not just posting a duplicate of something. If I am, I'm sorry.

My first question is about controllers. Let's assume I have two - or more - functionalities on the page I'd like to present:
1. The main functionality of the page, let's take a blog as example, since this seems to be the standard example everywhere.
2. User functionality: A user can be logged in, can log in, can log out, etcetera. Maybe the corresponding buttons for that user functionality will be displayed on a sidebar.
Obviously, the main controller will be the one handling the blog part. For the sake of clarity, though, I wouldn't like to put the user functionality into the same controller. Moreover, the user functionality will probably be used everywhere accross the site, not only on pages using the blog functionality. So I think that the user functionality should be given it's own controller.
Now the problem/question: How do I handle multiple controllers for one request? There will only be one "main-controller" per page, of course, which is getting specified by the URL; but still, how do I handle that stuff?


Second question - Models. I come from a non-webdevelopment background, and good practice was to have your data stored away in models, like here - But instead of having, for example, a "Post" model with every Post in it, you would have had an array of Post models, with 1 Post per instance of the model. I'm really confused as to how this whole stuff works here!
For example, I'd really like to have only one User per User model. But, if I now want to display multiple User's information on my page, how do I handle this? What is considered best practice here?
(Goal is mostly to separate the current logged-in - or not - user from any users on the page itself. The current user would be handled by my User controller, whereas the others wouldn't be, I guess?)

Third question - Views. Before finding CodeIgniter, I was reading about Ruby on Rails. I did not decide to use it, as I'd need to learn Ruby first, but one concept that should be applied everywhere, which was heavily advertised in every RoR tutorial, was "Don't repeat yourself". So I'd like to know: How do I move out some parts of a view that are bound to be used again in another view? Let's take our almighty blog: I want to have one template for displaying a blog post. And I may have two views: One for displaying an individual blog post, and one for every blog post. How do I move out the blog-post part so that it can be used in both views?

Next one: A long time ago, when I last coded a website, I used AJAX for responsiveness. No idea how it is done nowadays, but, as you could probably guess, the question is about responsiveness. What is best practice with CodeIgniter to adapt code for dynamic/responsive stuff, without losing basic functionality in case a user doesn't have javascript or something? Basically, should I make lots of controllers or controller actions for small AJAX requests? As in "Give me the view for a blogpost-create popup only"?


Uh, I think that was all for now. Thank you very much Smile
Reply
#2

(This post was last modified: 07-18-2016, 10:49 AM by InsiteFX.)

1,2 and 3 can all be handled by using the Wiredesignz HMVC Modules.

Download: Wiredesignz HMVC Modules

As for the Ajax you use it with CodeIgniter as you would on any other type of web site.

CodeIgniter doe's not restrict you in anyway.
What did you Try? What did you Get? What did you Expect?

Joined CodeIgniter Community 2009.  ( Skype: insitfx )
Reply
#3

Thanks for your answer!

I'm not saying that CodeIgniter restricts me - I'm trying to figure out the "best practice", aka how such a problem is usually solved while making good use of CodeIgniter's features and having a nicely structured code.
Basically, for (4) I thought of having additional actions that will be targeted by my client side javascript code. This idea seems ugly to me, though.

Thank you for the link! I think I get how they solve most of my problems. Although, it looks like I would have to load the additional controller/view from within another view - Wouldn't this be considered as a little "ugly"? In my head, I map "loading" to "logic", but the whole point of MVC is to render the visual part independent from the logic part, right? (I could be totally wrong, and probably am, but right now this is how I think of it - It would be really nice if you could maybe elaborate a little bit so I can grasp everything a little better.)
(Oh, and I also don't get how that addon would solve my "problem 2"?)

Thank you very much!
Reply
#4

Controllers and Models are not the only classes that CI supports. Basically, if you have functionality that needs to be used everywhere, I'd recommend putting it into a separate "Library" that can be called from any of your controllers. That leaves the controller to do their job of controlling the current page request, while not being the primary way of managing a certain topic.

HMVC is awesome for modularizing code, though, InsiteFX was right to point it out here, as it can be very helpful. Just don't forget that you have more options and your post made it sound like you weren't familiar with libraries.
Reply
#5

@kilishan

Thanks for the answer!

Well, I do know that I can simply put other functionality elsewhere, since CodeIgniter doesn't enforce any specific "coding style". I hadn't considered Libraries, but even now I do not think that they are the way I'd be happy to do things (Maybe I'm wrong, and they are).
My example mentioned above does apply very well, as I am trying to figure out how to properly include/handle an user system in my real application too. If the user system would only be a service/background task, using libraries would be fine, I guess - But I do want it to have its own controller for its own pages (Login page for example) anyway, so I'm wondering how to properly include that second controller into my main controller. Or how to include the "service" part into every page. (I'm not making any sense right now, am I? Sorry, I somehow have a hard time explaining myself on this matter...)
The same "problem" I mentioned in my last post will also appear here: I'd probably need a lot more controller actions if I want to, for example, have a "small" user thing at the top of every page, while still having some "real", normal sized user-only pages. And the idea of having such a huge lot of actions just seems a little ugly to me. (Not to mention the loading of a second controller in the view part belonging to the first controller. To me, it seems as if this were defeating the whole purpose of the MVC principle)

Also: Is there a way to make some actions only useable by the application itself? If I were to use the solutions provided above, with more actions for AJAX related code, for example, I wouldn't want those actions to be accessible by regular URL, I guess.



I hope I'm somehow making some sense. Sorry if I'm not...
Reply
#6

1) You can use a MY_Controller which can include other controllers auth controller, frontend controller and backend controller, these other controllers would extend the MY_Controller and your app controllers would then extend your one of the controllers in the MY_Controller.

2) In CI if you place a _ ( underscore ) in front of any class method it makes it inaccessible to the url.
_myMethod()
What did you Try? What did you Get? What did you Expect?

Joined CodeIgniter Community 2009.  ( Skype: insitfx )
Reply
#7

@InsiteFX
Thanks for your answer!

1) I'm kind of in a rush right now, so I'll reply to this later. Is that a common way of doing it?
2) I still need it to be accessible by URL, though. But it should only be call-able by my client-side code, and not the users themselves. (Basically, my AJAX methods will return "incomplete" html, without header and footer etc, or even just JSON, so I don't want the user to access that incomplete html/json. My javascript code will still need to access it.)
I thought about using some kind of tokens, but meh, I'm not sure.
Reply
#8

(This post was last modified: 07-19-2016, 12:21 PM by jaynarayan.)

(07-19-2016, 04:39 AM)Call-Me-Captain Wrote: @InsiteFX
Thanks for your answer!
(Basically, my AJAX methods will return "incomplete" html, without header and footer etc, or even just JSON, so I don't want the user to access that incomplete html/json. My javascript code will still need to access it.)
I thought about using some kind of tokens, but meh, I'm not sure.
you can Use is_ajax_request () method of input class . Return html only when it is an ajax request
          Heart  love codeigniter Heart
          Learning  best  practices
     Rate my post if you found it helpfull
Reply
#9

(This post was last modified: 07-22-2016, 06:35 AM by Call-Me-Captain.)

@jaynarayan
Thank you! Unfortunately, I don't want it to be accessible only by AJAX (I probably explained myself badly before, but by other system code, too. For example through the HMVC library's Modules::run. The only one that shouldn't be able to access the method by URL should be the user. But it's not that important - If there's no simple way of doing it, I'll just drop that.

@InsiteFX
I think I solved my previous problems with the way you suggested at first, using HMVC's library. I have one last question, though:
For similar, but different, reasons I'd need to create my own controller, just as you suggested, but from what I saw in the documentation, it looks like I will only be able to use my own, and no other - Which is not what I want.
Basically, how would I go about extending MX_Controller, and using that new class as a baseclass for some of my other controllers, without losing the functionality of those only extending MX_Controller or CI_Controller?

Here an example file system to illustrate what I'd prefer to end up with:

Code:
application/
     views/
          all.php
          of.php
          my.php
          views.php
     models/
          same.php
     controllers/
          stuff.php extends CI_Controller (I don't really need this one, though. All of my controllers could extend MX_Controller)
     modules/
          general/controllers/
               general.php extends MX_Controller
          other_stuff/controllers/
               other_stuff.php extends MX_Controller
          child/controllers/
               child.php extends general
          next_child/controllers/
               next_child.php extends general
          remaining_stuff/controllers/
               remaining_stuff.php extends MX_Controller


What happens when I visit the following URLs:

Code:
root/stuff:             stuff.php#index
root/general:           general.php#index     (<- This is my 'own' 'super-class' controller. Ideally, I should be able to decide wether this one can be 'visited' or not. But I guess that's simple enough with some basic routing.)
root/other_stuff:       other_stuff.php#index
root/child:             child.php#index (<- This one is extending general.php, as previously described.)
root/next_child:        next_child.php#index (Same)
root/remaining_stuff:   remaining_stuff.php#index


I hope that this makes what I want to achieve a little clearer?

It would be awesome if you or someone else could point out how I'd be able to do this Smile


Thanks!
Reply
#10

First, if you're using MX_Controller/HMVC, you shouldn't use CI_Controller as the base for any of your controllers. What InsiteFX suggested is basically creating a file, /application/core/MY_Controller.php, which contains all of the base controllers for your application (which would all extend either MX_Controller or another controller which extends MX_Controller). For example, I have:

PHP Code:
class Base_Controller extends MX_Controller
{
    
// ...


Then, for controllers which require authentication:

PHP Code:
class Authenticated_Controller extends Base_Controller
{
    
// ...


and for controllers in my admin section:

PHP Code:
class Admin_Controller extends Authenticated_Controller
{
    
// ...


and so on... These controllers don't contain routable methods, so no URLs call them directly. They are intended to provide functionality to controllers which extend them, so their methods are usually declared as protected instead of public (except the constructor). Since they are contained in the MY_Controller.php file in the /application/core/ directory, the system loads them automatically, so you can extend any of them with the controllers you use to handle your application's routes.
Reply




Theme © iAndrew 2016 - Forum software by © MyBB