How to use a helper in a controller

Published on and tagged with cakephp  controller  helper

A question asked from time to time in the IRC channel is: “How can I use helper X in my controller?”.

Well, helpers are not thought to be used in controllers. They are designed to be used in views. So whenever this question arises, you have to ask yourself (or others) whether you are doing something wrong and if there is no better solution.

Nonetheless, in some (rare) cases it can be useful to use a helper inside a controller to avoid code duplication. It can be accomplished in the following way:

class UsersController extends AppController {
    function index() {
        App::import('Helper', 'Html'); // loadHelper('Html'); in CakePHP 1.1.x.x
        $html = new HtmlHelper();
        debug($html->link('Cake!', 'http://cakephp.org'));
    }
}

Or, if you are using CakePHP 2.0, you can use the following approach:

class UsersController extends AppController {
    function index() {
        $view = new View($this);
        $html = $view->loadHelper('Html');
        debug($html->link('Cake!', 'http://cakephp.org'));
    }
}

Update 2007-08-13: m3nt0r has published a helper component in his blog which allows you to use a helper like a component. The article is in German, but the code should be self-explanatory.
Update 2008-06-07: Using App::import() instead of loadHelper() in the example. Thanks to mjamesd for the hint!
Update 2011: Adding snippet for CakePHP 2.0

38 comments baked

  • pablasso.com » Blog Archive » Helpers dentro de controllers en CakePHP

    […] Vía | CakeBaker […]

  • nate

    Could it be, hmmm…. Saaaataan?

  • rtconner

    Only time I’ve ever found it useful to use a helper in a controller is when I’m formatting an email for to send out, or formatting text to display in some fashion other than html (csv, perhaps). But I’m kind of learning the proper way is still to send the data to a view and format it in a view.

    Yeah once in a rare rare while helpers are needed in controllers though.

  • wluigi

    I use it for $time->daysAsSQL
    Maybe I m wrong using it like that

  • Nik Chankov

    When I start “baking” with that framework I try to access a Model in a View directly :D

    Now my mind is turned MVC, so this looking really odd to me.

  • bparise

    Here is a question to ponder…
    Say I have a single function that I want available to all MVC’s in my application. Where do I create it?

    This, IMO, is where making helpers “global” is helpful. I think many people when they hear “helper” don’t immediately assume its view related.

  • gribelu

    @bparise /app/config/bootstrap.php

  • cakebaker

    @all: Thanks for your comments.

    @wluigi: Yes, that’s one method I could imagine to use in a controller because it is probably by accident in a helper and not in a component.

    @bparise: That’s a good point. Maybe it would be easier to have one “global helper” concept instead of the three slightly different concepts “behavior”, “component”, and “helper”.

  • [m] webdev:blog

    CakePHP: HelperComponent…

    Als ich heute so durch meine RSS Subscriptions wanderte fand ich einen Artikel bei CakeBaker wie man in einem Controller einen Helper verwenden kann. Ich stimme natürlich zu, dass es nicht immer Sinn macht und eigentlich vermieden werden sollte, aber …

  • Yevgeny Tomenko

    Really there also one usefull topic when RoR developers use helpers insede controller. This is RJS calls. For the cake case this is CJS helper developed by the RoS.

  • cakebaker

    @Yevgeny: Hm, I never used RJS nor CJS, but shouldn’t you use them usually in views?

  • Yevgeny Tomenko

    @cakebaker,
    You does not disturb when you use $this->Session->setFlash in your controller.
    For example you write ajax driven application and one of your action just doing something and without refresh screen show text result. Will you create view with two line of code
    replace_html(‘#message’,$message); ?>
    effect(‘#message’,’Highlight’,array(‘duration’=>2, ‘startcolor’=>’#7777ff’)); ?>

    and use $this->set(‘message’, __(‘some_msg’,true)); in your controller.
    And if you have many such views you will not DRY.
    But you can create helper Msg with function
    showMessage ($message) {
    $this->Page->replace_html(‘#message’,$message); ?>
    $this->Page->effect(‘#message’,’Highlight’,array(‘duration’=>2, ‘startcolor’=>’#7777ff’));
    }
    and use this helper from controller like this:
    $this->Msg->showMessage(‘ok’);
    exit;

  • cakebaker

    @Yevgeny: Yes, that’s a possible solution to avoid creating too many very simple views.

    Personally, I have used a different approach to avoid such views. I created a one simple view with only one statement:

    <?php echo $text; ?>
    

    This view I rendered then from all places where I needed such a simple view.

  • mjamesd

    In CakePHP 1.2, “loadHelper(‘NameOfHelper’)” is depreciated. Use “App::import(‘Helper’,’NameOfHelper’)” instead.

  • cakebaker

    @mjamesd: Thanks for the hint, it is now fixed in the article!

  • maulana

    Damn, you save my life with this article, and I agree with bparise, global helper will be very helpful. Thanks Daniel

  • cakebaker

    @maulana: Cool to hear that :) And yes, it would be useful to have global helpers.

    Just curious, is your CMS realized with Cake?

  • rrd
  • cakebaker

    @rrd: Thanks for the link!

  • Brian Henk

    Thanks again for the help. I agree with the original premise of helpers though – you shouldn’t be doing anything that the user sees in the controller (at least not finally).

    The problem for me came in the form of AJAX requests, which forwarded some controller generated JSON.

  • cakebaker

    @Brian: I’m glad to hear this article was helpful for you!

  • Jiruus

    hii,
    echo '<li onClick="fill(\''.addslashes($results['members']['name']).'\');">'.$html->link($results['members']['name'],array('controller'=>'members','action'=> 'view')).'</li>';

    After running this code, when I’m clicking on the result it will go to http://localhost/members/view . but I can’t pass the ID along with ,then only I can get the corresponding view of the member. like http://localhost/members/view/2

    plz help me

  • cakebaker

    @Jiruus: Well, you have to pass the id as third array element, see the documentation of the link method.

    Hope this helps.

  • Stephen

    I found this quite useful when dealing with the XML helper.

    This allowed me to generate an xml file, send it to ftp and have it picked up by our in house order processing system without having to generate a view for the controller.

    Keep up the useful posts cakebaker

  • cakebaker

    @Stephen: Cool to hear this was useful for you :)

  • will

    How would you do this in 2.0?

    Using this method, (which worked great for 1.3 btw) i get:

    Argument 1 passed to Helper::__construct() must be an instance of View, null given

    Will

  • cakebaker

    @will: Thanks for your question!

    I would use the following snippet:

    $view = new View($this);
    $html = $view->loadHelper('Html');

    Hope this helps!

  • will

    awesome, thanks!

  • Jose

    Thanks a lot. I need id for build dinamic links relative to the users role in the authentication.

  • cakebaker

    @Jose: You’re welcome :)

  • mark

    If you are using cake2.x you should refactor your code. for core helpers to use the new lib classes or for your custom helpers to move all helper code into a lib and reuse it in the helper: http://www.dereuromark.de/2012/04/10/cakephp-now-fully-mvc/

  • cakebaker

    @Mark: Thanks for the link!

  • peermydeen

    yahoo !!!!!!!!! i got it thank u ……………….

  • Larry

    The only use-case I have for calling a helper from inside a controller is to generate links. Sure, I can generate the link in the view, but I have a case where I want to pass in a name=>value array for a table. Some items are links, some not. So I’d still have to find a way to tell the view which items to render as links and where to point them to and what text to use. Doable of course, but it seems like less work if I can render render those links inside the controller so the view (actually element) just sees an homogeous array of name=>value pairs and it just treats each value as a string.

  • Rafael

    Perfect! Thank you!

    Regards from Brazil :D

  • Ram

    It worked.

    Thanks.

  • namnd

    Perfect! Thank you!

  • Ben

    Never understood this “cant use helper in controller” thing.

    A helper is just a bit of convenient code, and if you look at the likes of Smarty it encourages view stuff to be processed in teh controller and sent to the view.

    What if I, for ajax, echo out string with a price that I want formatted with a pound symbol. I need to use the Number helper.

    Look at CodeIgniter, it appreciates this and helpers can be used anywhere, because they’re helpers!!!

  • URL

    … [Trackback]

    […] There you will find 44626 more Infos: cakebaker.42dh.com/2007/08/09/how-to-use-a-helper-in-a-controller/ […]

Bake a comment




(for code please use <code>...</code> [no escaping necessary])

© daniel hofstetter. Licensed under a Creative Commons License