Hi guys,
i’d like to hear your opinions on a idea i had about storing a “click path” (in abscence of a better name). Here’s what it’s about. Sorry, if this get lengthy
One fact somehow prevents me from reusing some of my actions: I always need to know either
a) what view to render after the action or
which URL to redirect to.
If i use static values here, this prevents me for example to reuse a delete or save action in different places.
To discuss a solution i'd like to use a small example. Here some actions with sketches of the according views:
user/list:
Show a list of users with link to edit or delete a user (and a link home).
[Home] John Foo [edit] [delete] Jim Bar [edit] [delete]
admin/userlist:
Also shows a list of users, maybe enhanced with some more admin features.
[Home] John Foo [edit] [delete] [change group] Jim Bar [edit] [delete] [change group]
As we see, both have a link to edit a user.
user/edit:
Shows a form to edit (maybe also create) a user.
[________] Name [Save] [Cancel] [Delete]
It would be great to use the same action/view for both edit links, so that we could for example have these click paths:
Actions User A: user/list -> user/edit -> user/save -> user/list
Actions User B: admin/userlist -> user/edit -> user/save -> admin/userlist
So we somehow need to save, where the user came from, to decide where we have to return to after he clicked save/cancel/delete on the edit page. The only (cross-tab-browsing safe) way to do this, is to add the return information to the URL when we call user/edit.
My idea now is like this:
Just like with CSort, we can add information about the clicked actions/parameters to an URL. This would only happen on demand, of course. The click path could be an array of route/page parameters (or maybe just return URLs). That way we can even create a queue of pages that we want to return to after the current (and maybe even next) action finishes.
How would we add a page to the click path:
We can differ between three types of links/URLs:
1. Links to pages from where we don’t want to return to this page.
This would be the "Home" link for example. It would be created with createUrl() as usual.
2. Links to pages from where we might return to the current page
In user/list above we would have to add the return information to every edit link. The best place for this would be CController::createUrl(). So the [ edit ] link could be constructed with:
<?php // Note the value 'addReturnUrl' (without key!) $this->createUrl('user/edit',array('id'=>$model->id, 'addReturnUrl');
When 'addReturnUrl' is present, CController would check, if the current request's URL already supplies clickpath information (maybe we even have to return to another page after user/list) and add the current route/page paremeters to the list of these pages. So it would add maybe a c[] array to URL parameters like this:
..&c[0][q]=user/list&c[0][sort]=name&c[0][otherparam]=...
3. Links to actions that are “end points” of a click path
Links to actions on the user/edit page are special, as they are "end points" of a click path. That means, afterwards we want to return to the last page before the current page. So for the save/cancel/delete URLs, we would need to add the current click path, but not add the current edit page.
<?php // Note the value 'useReturnUrl' (without key!) $this->createUrl('user/edit',array('id'=>$model->id, 'useReturnUrl');
This time only the clickpath from the request URL is added again to the created URL. But the current route/parameters are not added.
How would we use the clickpath to find out the return URL?
A ClickPathManager could be accessed by CController::clickPath. It would manage a list of pages, we want to return to. And it could provide a getReturnUrl() method, that delivers the last URL we want to return to.
So if in actionSave() in UserController above we could do something like this:
<?php public function actionSave() { // Do save logic here... if ($returnUrl=$this->clickPath->returnUrl) $this->redirect($returnUrl); else // Redirect to some default URL if no return path is available }
This is only a rough concept. But does that make sense to anybody else at all? What did i forget?
Comments welcome!
Update:
This is an extension now. See http://www.yiiframew…on/xreturnable/