A missing convention

Published on and tagged with cakephp  convention

In CakePHP we have many conventions which tell us where to place certain files: controllers are placed in app/controllers, models in app/models, views in app/views, and so on. Only for one category of files there is no (explicit) convention of where to place them: the files containing “normal” classes you want to use anywhere.

According to a comment by gwoo those files should be placed in the vendors folder: “Vendors is fine. Any classes that are not part of the MVC are considered 3rd party classes.”

Sure, this works. Only, it means you have to mix two different concepts: on the one hand you have classes you get from someone else (the “vendor”) and which you usually don’t touch (and often don’t follow the Cake conventions), and on the other hand you develop your own non-MVC classes following the Cake conventions in the same folder. To me this doesn’t feel right…

And so I think there should be a convention like “Non-MVC classes are placed in app/libs” to separate “internal” and “external” libs and to show in the “app” folder the fact that an application (often) consists of utility classes and external libraries.

Such a convention would also help to avoid comments like the following comment for a class defined in a AppModel: “q: Why is this in the app_model file? a: Because we couldn’t really think of a better place. Suggestions are most welcome.”

11 comments baked

  • nate

    Seems to me you’re trying to look for some pattern or separation where there really isn’t one.

  • Brendon Kozlowski

    IMHO, I think he’s looking for a better way of file/class organization and hierarchy. Since we already have one set up for us within the framework, it makes sense to try to use its own hierarchy and organization to separate out our own.

  • skiedr

    I preffer to use app/libs folder for this purpose.
    I declare constant APP_LIBS in bootstrap.
    And use next import for include my own lib.
    App::import(‘File’, ‘MyCoolLib’, true, array(APP_LIBS), ‘my_cool_lib.php’);

  • Chris Forrette

    I think this is what Nate & Brendon were trying to say, but why wouldn’t you just use the existing models/views/controllers directories to put your classes into as they relate to those three legs of the framework? What’s an example of a class you’ve built like this? I guess can’t quite relate because everything I’ve had to use with Cake has either fit in vendors or just extended one of the existing classes and gone into behaviors/helpers/components.

  • dr. Hannibal Lecter

    A peculiar idea.

    Wouldn’t it be more simple to just create a sub-folder in vendors for your own libs? You get both the separation and you can use the built-in App::import(…).

  • David Persson

    For me it feels wrong to put my own classes into a vendors folder, too.

    I really would like to see a change of the default folder structure or an insight into the logic which is behind the current one.

    The naming of the vendors folder always irritated me.
    Maybe it’s because I’m not a native speaker and the *only* thing that comes to my mind when I read “vendors” is “3rd party”.

    From the POV of the framework itself, every other lib (not part of MVC) is a vendor lib.
    Following this logic should I put the cake libs (not part of MVC e.g. the Xml class) into my vendors folder? Certainly not.

    So… what is a vendor class? What is a lib? And what is actually part of MVC?

    Seems nate is right and there is no pattern of seperation (necessary) between libs and vendors.

    But when there is no difference between them, then my suggestion is to rename the “vendors” folder to “libs”.

    And how would we import the classes then?
    App::import(‘Core’ …) for the core libs
    App::import(‘App’ …) for the app libs

  • cakebaker

    @all: Thanks for your comments!

    @nate: I’m looking for a better way to structure cake applications. For me an application consists basically of the following logical parts: model functionality, view functionality, controller functionality, non-MVC functionality, and 3rd party libraries. And so I think this should also be reflected in the structure of the “app” folder and the conventions.

    @Brendon: Yes.

    @skiedr: Yes, that’s probably the approach I have to adopt myself.

    @Chris: Well, not everything does fit into the MVC structure. An example is a utility class which fetches the content of an url, and is used in models and components. Other examples are the classes in the cake/libs folder. If they wouldn’t be part of the framework, where would you place them if you have to write them yourself?

    @Hannibal Lecter: *g*. Sure, you can create a subfolder in the “vendors” folder and place your own utility classes there. But as I described in the answer to nate, for me an application consists of five logical parts, MVC plus non-MVC classes and 3rd party libraries, which I think should be represented in the “app” folder.

    @David: For me a vendor class is a class which wasn’t written specifically for cake and hence doesn’t follow the cake conventions. It is usually maintained by someone else.

    On the other hand, a “lib” class (maybe non-MVC class is more suitable) is a class which doesn’t fit into the MVC structure and is written and maintained by myself.

    Somehow it is similar to the “app” and “cake” folder: by convention you work in the “app” folder and you don’t touch the “cake” folder. If we adapt this convention, we could say: you work in the (not yet existing) “libs” folder and you don’t touch the “vendors” folder unless you have to add/update/remove a 3rd party library.

  • naonak

    Just put this in core.php :

    $vendorPaths = array(APP_DIR . DS . 'libs');

    You allays need to use App::import('Vendor', 'my_on_lib'); but files are physically separated.

  • dr. Hannibal Lecter

    This brings another issue in my mind..

    If you create a library, and put it in your new lib folder, then I get the library from you, where do I put it? It’s third party, not maintained by me, but it’s your library. For the sake of the argument, let’s say we’re best pals working in a company together, but on different projects.

    Vendors or libs?

    (I obviously need coffee ASAP:))

  • cakebaker

    @naonak, Hannibal: Thanks for your comments!

    @naonak: Yes, that’s a step in the right direction!

    @Hannibal: The decision is quite simple. You have to ask yourself the following question: would you write tests for it in your application (if you are into testing)? If yes, it goes to the libs folder, else to the vendors folder.

  • dr. Hannibal Lecter

    After giving it some thought, I think your suggestion makes sense. My own libs are indeed “vendors”, but obviously there are many situations where I wouldn’t want to mix them with “4th party” vendors :)

© daniel hofstetter. Licensed under a Creative Commons License