I have a CMS base controller that most of my other controllers extend. It has a default action for list, create, read, update and delete actions, all of them set the title based on the name of the resource(s) the user is working with.
The index action defaults to contain only one row:
$this->_forward('list');
Now my problem is that my previously set title is gone when I open the index of a CMS controller. I'd like to know what could be happening and what is the best solution of this.
Note that the problem does not appear if I rename my list action to index. It may also be relevant that changing the view title in the index action does not work.
Hmm, where do you set your title and in what way do you do it? Personally my titles are only two parts like "Application: current action". To achieve this i do the following:
//layout.phtml
<?=$this->headTitle()->setPrefix('APP: ')?>
//indexAction()
$this->_forward('list');
//listAction()
$this->view->headTitle()->append('List Data');
I do this for every action separately and since i do not assign a title within indexAction() i get the full wanted title "APP: List Data" inside listAction(). This remains true if i have my edit action like the following
//editAction()
if (!is_numeric($this->_getParam('id'))) {
return $this->_forward('list');
}
If this doesn't do it for you, your scripts will be needed to look for an error elsewhere :)
Actually, my initial idea of this issue having to do something with routing was right. I'm loading the layout in a preDispatch action of an action controller. So what actually happend was that I re-created my layout view after setting the title attribute in the index action.
Related
I would like to know what is the best method to have an action return different views. Let's say you have a form for submitting data, but you want to choose the view depending on what data is submitted. I would prefer not using a redirection, since there is stuff I want to be displayed in the data that is posted.
An example of this would be to have an Edit form that displays a Details view when clicking on Save, but without using a redirection.
I know this could be done with a single view containing a conditional if statement to display this or that, but there are cases where I would prefer my views to stay simple without too much code in them. If the controller could just choose the view to display once the data is posted, this would be great.
There is an overload to the View() method that allows you to specify the name of the View you want to return.
return View("DetailsView", model);
You should be using the Post/Redirect/Get pattern. You can still "display stuff." You can pass an ID on the URI and look them up in the new GET or use TempData.
Attempting to circumvent Post/Redirect/Get is not a good solution. Among other things, it breaks the back button.
I am trying to create a sidebar in my layout that has the behavior of a placeholder. I want to be able to define the contents of this placeholder once per controller. So every controller can add custom content to the sidebar but without the need to define it in any view.
I am kind of confused on how to go about that with Zend_Layout. Any help?
I have tried something similar. Here is what you can do.
Place this type of code in the layout.phtml script file. Somewhere near the top. You don't have to but this way you 'know' what placeholders you're using. Doing this in the layout is also a good idea because you can wrap html divs are whatever here and not worry about it in the views. The views can just worry about the content. After this, you can add content to the placeholders from the controllers and the views.
$this->placeholder('blah');
$this->placeholder('sidebar');
$this->placeholder('blunk');
If you don't want to create them in your layout, then you can do it in the controller like so,
$this->view->placeholder( 'sidebar');
.
Now, you can either put content into it in the controller, or in the view script. Its a better idea to add the content in the view though.
In the layout you can then just echo the placeholders like so
echo $this->placeholder->( 'sidebar' );
All the views are executed BEFORE the layout is executed so any placeholders created by the views will be available to the layout to print out.
Also, controllers don't HAVE placeholders. Only views, and by extension layout, have placeholders like this so you have to declare them somewhere. Even if you declare them in the controller they still 'belong' to the view object.
I don't know if this helps at all but good luck. Tell me what you think.
How about adding a postDispatch() call to each controller?
public function postDispatch()
{
// code to populate/activate your placeholder
$this->view->placeholder('xxx');
}
This function will be called after your action completes. For more info, see Pre- and Post-Dispatch Hooks.
i have just implemented a solution to this that should work for most uses.
I store all of my placeholder.phtml files in the following dir:
/views/scripts/_placeholder
Within the placeholder i create directories for each Controller / Action that has a placeholder (as well as ROOT stuff). I then create a file for each placeholder.
e.g. Placeholder = sidebar. Controller = user / action = view
for the above we would store a file here:
views/scripts/_placeholder/user/view/sidebar.phtml
note: within the sidebar.phtml you will need to add : $this->placeholder("sidebar")->captureStart() and captureEnd();
if the plugin sees this file it will render it. If it doesnt find one then it wont.
Additionally the plugin will also look for the following and pull that in first:
views/scripts/_placeholder/sidebar.phtml
I can post the plugin if you want.
The only issue i have is i would like to now know if a placeholder has any data in it. That way i can create some layouts that are clever and will render what needs. DOes anyone know how to do this?
how can I pass an object model to a view, that is partial view on a master page?
regards
You might consider creating an another object that more closely represents the view you are trying to render.
Let's say i have an MyDomain.Order object, so I make a view page that looks something like ViewPage<MyDomain.Order>. Now, let's say that I have a menu that is driven off of a logged in user, as example. It wouldn't make sense to have menu as a property of MyDomain.Order. I would create another object, specifically for the view, call it something like OrderPageModel and have MyDomain.Order and List<MenuItem> as properties of this new object, my view being set up as ViewPage<OrderPageModel>.
The other thing to consider might be something like Html.RenderAction(). Same scenario, I have a view, and as you mention in your question, it has a master page, and as in my example, lets say it hosts a menu common to your site. You could create a partial view (UserMenu.ascx) and a controller (SiteController.cs) with an action (UserMenu) that calculates the items for the menu. Inside your master page, you can then call <% Html.RenderAction("UserMenu","SiteController") %>.
I would use the first example if it could be something made for a particular view: just make it a part of the model. I would use the second example if it was something more generic to the site, like a menu.
You could specify the location of the view:
return PartialView("~/Views/SomeOtherController/SomePartial.ascx", someModel);
Best bet here is RenderAction over RenderPartial. Your child controller can easily figure out if the user is logged in and render the right partial rather than making your master page worry about these details.
I have a one form tag inside my Index.aspx view. Index.aspx contains several partial views and using the same model to render them.
Now when any partial view is posting the form with submit button form is posted to OneActionMethod. But I want for some partial views to post form to OtherActionMethod.
How can I achieve this, without using action links, just with submit button in this particular patial view?
I`ve wrote the update in comments to this question. Answer is still not clear to me.
i believe a little javascript will get ur job done. u have to hook the submit event of the form and change the action attribute of the form. remember action is attribute of form not of a submit button. in jquery u can do something like
$("#myform").submit(function(){
if(isFirstSubmitButton){
$(this).attr(FirstAction);
}
else if(isSecondSubmitButton)
{
$(this).attr(SecondAction);
}
return true;
});
You sound like you are trying to program "WebForms" style in MVC.
Why do you have one big form enclosing all of your partials? Separate them into unique forms, and have each one post to it's appropriate action.
EDIT: With your further clarification, the only thing I can think of (aside from redesigning to use individual forms, which does lead to problems if they want to share data), is to post to a single action, and then route the request to a private member within the controller for ActionA or ActionB depending on a particular form element.
I am experimenting with Zend_Navigation to build breadcrumb for a web site. I created an XML file which lists the hierarchy of pages. Things are working fine for the most part except for pages that have dynamic parameters.
For example, there is a group page which has the URL " www.../groups/gid/1001". The id 1001 is dynamic so it changes for different groups. Because of that I cannot put it in the XML file. In that case, ZF generates a link without including any parameters, which of course won't work.
One solution I found is dynamically injecting the parameters to the Zend_Navigation object. This is working fine except that I need to do it for each action or controller.
Is there a better way to handle it? Does ZF have any classes to do this work?
I will appreciate any feedback.
Thanks!
http://zend-framework-community.634137.n4.nabble.com/Creating-a-dynamic-database-based-Zend-Navigation-item-td660805.html
And/or start reading here: http://framework.zend.com/manual/en/zend.navigation.introduction.html
At which point do you know the group ID to use in the navigation?
If it's early enough, you could simply create your own bootstrap init method to insert the navigation item, just remember to call $this->bootstrap('navigation') at the top of your method, eg
protected function _initCustomNav()
{
$this->bootstrap('navigation');
$navigation = $this->getResource('navigation');
// add custom item
return $navigation;
}
Disclaimer: I'm pretty sure the navigation resource is just called 'navigation'