For a lot of my view controllers, I do not have an index action. Is this bad practice?
After looking through a lot of sample applications I see that almost all applications that don't use an index action, at-least declare the following:
public function action_index()
{
$this->request->redirect('');
}
Is it best practice to at-least have this index redirect for each view controller or is it perfectly acceptable to not even declare such method as I am currently doing?
You don't need to declare action_index method.
Simply set default action for route to something else than "index". Example
Route::set('default', '(<controller>(/<action>(/<param>)))')
->defaults(array(
'controller' => 'welcome',
'action' => '*your_action*',
));
Related
I have a route defined on my controller action
[Route("xxx/{xxxId:int}/yyy/{yyyId:int}/Details/{editable:bool}")]
I have used 'preservedRouteParameters' and managed get the breadcrumb showing
My mvcSiteMapNode is like this:
mvcSiteMapNode title="TheTitle" controller="yyy" action="Details" preservedRouteParameters="xxxId, yyyId, editable"
I'd like to have the breadcrumb url contain the Id for the previous stage. i.e. xxxId.
Can anyone help with how to achieve this?
[edit]
Having played with it a little more it seems that the problem I have is that my 'id' is not named consistently.
In the parent I have 'id' and the sub page I have 'xxxId'
Changing them both to be just 'id' seems to have worked.
I'd like to have the layout reflect some data from a model. However, the render method from the CController class passes the structured data only to the view file, while the layout file only gets the rendered view passed.
So, how to best have the layout display data from a model?
Two possibilities come to mind:
Make Yii's layout file a no-op, mimicking layout logic manually from the view.
Override CController's render method in its subclass.
I'm not so happy with either variant, so maybe someone has a cleaner idea on how to do it?
Another way is to define a public variable in your controller class, something like:
class MyController extends Controller {
public $test = 'foo';
....
That value can then be accessed within a layout:
echo $this->test;
And manipulated in an action:
public function actionMyaction(){
$this->test = "bar";
...
Obviously it's not ideal if you have many variables that you need to use in a layout. One solution is to use an array of parameters. Alternatively you could look at making your layout more minimal and using CWidget to create reusable components for use inside your views.
For example, you obviously wouldn't want to have the code for your main navigation duplicated inside every view, so the obvious solution is to have in the layout, but if it becomes inconvenient to handle the data you could have an instance of a widget that renders out the navigation inside each view (and you can pass data to the CWidget class) something like:
$this->widget("MainNavigation",array("params"=>$params));
I've looked around, and there are a few links about this in Zend 1 at best. The best solution I've found is
// controller:
return array('viewValue' => 'something');
// layout.phtml
$children = $this->viewModel()->getCurrent()->getChildren();
$viewValue = $children[0]->viewValue;
In the layout, but it seems a little kludgy. It's even stranger because when I do get_class_methods on the layout it doesn't show a viewModel() method. Basically, I've looked around the API (and source code) and haven't found much. Zend 1 also seems to have more access; some old solutions involved getting the view, and directly modifying it, but in Zend 2 we return a new array (or view model). Any tips?
As for why, I'm using a jQuery mobile layout. So the heading is separate from content, but the structure should be the same (should belong in the layout).
The view models are hierarchically build. The top level view model is the "layout" and a child view model is injected after a controller is dispatched. This means you can build quite some tree of models for your application.
The top level view model (so the one representing the layout) is also located in the MvcEvent. That object is passed along in the application during bootstrap, but also linked to the controller when the controller is initialized.
The MvcEvent is accessible with $this->getEvent() in the controller, the view model by $event->getViewModel(). So to cut things short, just do this:
controller MyController
{
public function myAction()
{
$this->getEvent()->getViewModel()->foo = 'bar';
}
}
And in your layout.phtml:
<?php echo $this->foo; ?>
This pretty much is, how it is done. The new Zend\View-Components are pretty much all ViewModels nested into each other. Rob Allen has written a great article about it on how to work with variables throughout ViewModels.
Furthermore most often i think this approach isn't the best way. It'd be much better to have a ViewHelper or a Layout-Placeholder to do the job. Once again a great article has been written, this time by my dear Bakura, aka Michael Gallego.
Currently, either of those approaches would be your way to go.
I am trying to have the render name in my jade
I could do:
app.render('email', { render: 'email' }, function(err, html){
// ...
});
but I'd like to know if there is a solution to get it automaticly
Thanks
I have found it helpful to write a wrapper function around render that takes a response object, a view name, and any additional options. I then use this function exclusively instead of res.render. My implementation does things like automatically decorating the title, assigning a unique view id to all views, etc. I use it like:
render(res, 'user.new', {title: 'sign up'});
In this example, the function takes the view name 'user.new' and gives it a unique id: 'user_new_view' assigned to the body element. In your case you could simply pass the value to your template.
The benefit of this pattern is that a single function acts as an interface to all of your views (assuming you use it consistently), so if you need to change the information passed to your views you don't have to edit every endpoint in your application.
I've been thinking how to make something like this in Kohana:
domain.com/variable
the "variable" is the identifier for a user.
So, is this possible?
http://domain.com/username/controller/action
If yes, can you point me to the right direction, please?
Thanks.
What happens if you have a page named "contact" and a user signs up with "contact" as a username. Which page will be displayed?
Here is an example I threw together for you.
// Pages that aren't users.
Route::set('static', '<action>', array('action' => 'sitemap|faq|terms|privacy|credits'))
->defaults(array(
'controller' => 'static'
));
// User routing
Route::set('user', '<username>(/<controller>(/<action>))')
->defaults(array(
'controller' => 'user',
'action' => 'index'
));
So when this URL is called
http://example.com/sitemap
the first route is used and when
http://example.com/arnold
is called your user class and index method would be called. You can access the username variable with:
$this->request->param('username');
If you have any more questions, feel free to ask.