Creating Reusable Elements with requestAction
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.
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.
Now we have the element we can include it in the layout, another element or a view template.
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.
Notice we changed the index action to use paginate instead.
In the view we can use paginate params to control what is returned.
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.
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.
Start of with a simple controller.
Controller Class:
Download code
<?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:
Download code
$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:
Download code
<?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:
Download code
<?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:
Download code
$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:
Download code
<?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.
Comments
Comment
1 Awesome
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
Comment
2 My 1.2 and I.
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.
Comment
3 Using a parameter in element
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.
Question
4 great
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
Comment
5 How now shall we live
Comment
6 Examples
Greetings, Benni.
Comment
7 Cross module activity
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?
Comment
8 Elements vs. mini views
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.
Question
9 One problem
"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
Question
10 Integration cakephp with wordpress and wikimedia
Question
11 view using many controllers
thanx
Question
12 Reusable Elements
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?