Creating Reusable Elements with requestAction

by gwoo
This is a brief tutorial on using requestAction to produce reusable elements. Code samples for 1.1 and 1.2 are provided.
Creating reusable elements with requestAction is very simple. At the end, we can even cache the element using the new feature in 1.2.

Start of with a simple controller.

Controller Class:

<?php 
class PostsController extends AppController {
    var 
$name 'Posts';

    function 
index() {
        
$posts $this->Post->findAll();
        if(isset(
$this->params['requested'])) {
             return 
$posts;
        }
        
$this->set('posts'$posts);
    }
}
?>
So, we created the Posts controller and we gave it an index action. Then we found all the posts, then if requestAction is used it will return the posts, otherwise it will set the posts for the view.

Now we can create a reusable element that will use requestAction. We create a file in /app/elements/posts.thtml, then add the code below.

View Template:


$posts = $this->requestAction('posts/index');
foreach($posts as $post):
    echo $post['Post']['title'];
endforeach;

Now we have the element we can include it in the layout, another element or a view template.

View Template:


<?php echo $this->renderElement('posts');?>

The code above is for 1.1. If you want to get into the goodness of Cake 1.2 you can look at the updated code below.

Controller Class:

<?php 
class PostsController extends AppController {
    var 
$name 'Posts';

    function 
index() {
        
$posts $this->paginate();
        if(isset(
$this->params['requested'])) {
             return 
$posts;
        }
        
$this->set('posts'$posts);
    }
}
?>
Notice we changed the index action to use paginate instead.
In the view we can use paginate params to control what is returned.

View Template:


$posts = $this->requestAction('posts/index/sort:created/direction:desc/limit:10');
foreach($posts as $post):
    echo $post['Post']['title'];
endforeach;
Now we are only grabbing the latest 10 posts. Whoa, we just created a latest posts element without having to change our index action or create another action.

Lets call this one latest posts and cache it for an hour.
create the file /app/elements/latest_posts.ctp.

View Template:


<?php echo $this->element('latest_posts', array('cache'=>'+1 hour');?>
We can still use this element in any other view file.

There are other ways to use requestAction, but if you are looking to create reusable elements for your site, then this is the way to go.



Report

More on Tutorials

Advertising

Comments

  • adeblas posted on 01/03/11 04:01:05 AM
    I've followed this example succesfully, but I had to add

    $this->autoRender = false;

    in order to override the lack of views for the method.
  • dahousecat posted on 11/05/09 04:35:57 AM
    Only a small point but I believe that this is a typo:

    "We create a file in /app/elements/posts.thtml, then add the code below."

    should read:

    "We create a file in /app/views/elements/posts.thtml, then add the code below."

    Unless I'm actually meant to make a folder in app called elements?!?!
  • majna posted on 03/19/09 12:01:41 PM
    @Siegfried Hirsch
    There's no need to extended the element()method,
    U can use 'key' and 'time' param:
    echo $this->element('news/latest_news', array('cache'=>array('time'=>'+1 hour', 'key'=>'my_key')));
  • lupus posted on 03/09/08 08:29:46 AM
    How to translate this code in smarty?

    View Template:

    $posts = $this->requestAction('posts/index');
    foreach($posts as $post):
    echo $post['Post']['title'];
    endforeach;

    I don't know how to connect (smarty) view element with (cake) controller?
  • mafo posted on 11/11/07 03:11:36 PM
    Hi, i'm new in cakePHP and I want to know what's the convention to make a view that uses more than 1 controller. I mean, i have a view that shows a list of messages and a list of events. Where should I put the view file? in wich folder? Should I use elements?

    thanx
  • anuj posted on 08/23/07 05:01:59 AM
    i want to integrate wordpress and wikimedia in my project base on cake framework, but no idea how to do it, is there anyone who did it before or have any idea on this
  • josejimenez posted on 08/21/07 12:37:21 PM
    Hi, i did it, same as you explain. But my browser shows me an error:

    "Safari can’t open the page.
    Too many redirects occurred trying to open “http://localhost/cake/”. This might occur if you open a page that is redirected to open another page which then is redirected to open the original page."

    Any idea? Thanks
  • brammeleman posted on 07/30/07 02:05:06 PM
    My initial thought of requestAction was about embedding a view into another view. Literally.
    Instead of just reusing a controller action and a view. You need to adapt the controller action to behave differently when it's 'requested' or just called in the normal way.

    Would it be possible to just include a 'mini view' from another view? For example: When I want to show a selected contact above my contact list. It then makes sense to create some sort of mini view for the selected contact. You can create / test / debug it by pointing your browser to /contacts/smallview/454. Once it works, include it with:

    $this->requestAction('/contacts/smallview/'. $id);
    Directly from your view where you would like the mini view to appear. That's it, no more fiddling around with sending the data to an element / lopping through arrays, etc.
  • bingomanatee posted on 07/16/07 11:44:48 AM
    Willing to except that we're all "bad programmers" but hey:

    what is the right way to access controllers / models across Cake? for instance, I'm doing a one-to-many update where "Model_A"' is related to "Model_B" by a foreign key in "Model_B". in the "Model_A_controller"'s "update" function, I'd like to either get an instance of a "Model B" object or pass control to "Model_B_controller" and let it do the work. What is the "good programmer" way to do so?
  • benni posted on 06/26/07 10:01:31 AM
    Could you explain why or, even better, give examples? ;-)

    Greetings, Benni.
  • nate posted on 06/09/07 07:59:39 PM
    That being said, y'all need to stop using requestAction. While I recognize and fully support the fact that there is an occasional need for it, more often than not, it is evidence of poor design, and you're doing something that could be done differently, or more likely better.
  • ragrawal posted on 05/17/07 09:18:52 AM
    hi Gwoo,

    for long, I was looking for something like this..however, in my website, users have a choice to sorting the latest post either by created date or modified date. How can I use the above reusable element to change the created,sort, and limit parameter based on user's choice.

    Ritesh
  • Siegfried posted on 05/08/07 01:34:16 AM
    I like the new approach with the element() very much. I started implementing a very small contents_controller, just for displaying some content, which could be edited by the user.

    I get the information from the controller, as shown above, but every page has a different parameter $page. Because this is static information most of the time, caching makes a lot of sense. So I have also included the 'cache' => '+1 hour' to cache the requests.

    The problem is, that I only have one element, which is used for the different pages, because I use a $page var from the controller to request the different pages.

    So I have extended the element() implementation in view.php a little bit like this:

    if($expires) {
    $plugin = null;
    if(isset($params['plugin'])) {
    $plugin = $params['plugin'];
    }
    // this is new <<<<<<<<<<<<<
    $param = null;
    if(isset($params['param'])) {
    $param = '_'.$params['param'];
    }
    // param parameter to extend the cacheFile name
    $cacheFile = 'element_' . $plugin .'_' . convertSlash($name).$param;

    Maybe somebody has a better idea for this, but I don't wanted to create a different element for every content page, that I have to create. Now with the new parameter 'param' I could extend the call for element with a additional parameter and the elements are cached in different files in APP/tmp/cache/views

    // the call for element with additional parameter
    // 'param', which is my variable $page
    echo $this->element('content', array('cache' => '+1 hour', 'param' => $page) );

    looking forward to get some hints on this.
  • neilc posted on 04/13/07 03:49:42 AM
    Wow, this is great, so useful. I never realised requestAction() could be called from the view like that, although I guess I should have realised it, if not this way, then through the view->controller->requestionAction() path.

    The stuff in 1.2 looks brilliant - but I'm still using 1.1x for all my projects because its the "stable" version. How unstable is 1.2? Would you recommend using it on large scale client websites? If not, do you know what the schedule is for a stable release of 1.2?

    Is there any documentation currently available about the differences between 1.1 and 1.2? It seems there's quite a lot.

    Finally, on that note, are there sufficient differences to warrant a new major version release? Cake2.0
    • websta posted on 04/16/07 01:57:26 PM
      The stuff in 1.2 looks brilliant - but I'm still using 1.1x for all my projects because its the "stable" version. How unstable is 1.2? Would you recommend using it on large scale client websites? If not, do you know what the schedule is for a stable release of 1.2?

      Is there any documentation currently available about the differences between 1.1 and 1.2? It seems there's quite a lot.

      I dived in and begun using the 1.2 branch a couple months back for two "large enough" commercial projects - a paid online magazine and a real estate portal.

      While i have had the odd challenge thrown my way with some code behaving badly and at times a shortage of documentation for some of the cooler features of 1.2, a quick search through the user groups, the trac or just hitting good old google, has given me all the answers i could need without too much hassle!

      So my two cents would be, go for it so long as your willing to put in a little extra effort - which in the end isnt really extra time as some of the magic 1.2 can do for you almost has me worried i shall no longer be needed in the world of webdev. (its doing it all for me)

      and a parting note too - there has been a new release of the 1.2branch which im told has cured some of the most common ailments reported.
login to post a comment.