How do you add in the yii form the action for PHP_SELF, I am currently using this:
'action' => '/site/contact',
but I want to replace the action to call itself again. How do I do that?
UPDATE:
tried removing the action in the array, now it does not go into validating the form.
Use Yii controller method createUrl - calling it without params will point to current controller and action.
In views you can just call $this->createUrl():
'action' => $this->createUrl(),
Important: do not hardcode actions like in your question. Always call createUrl, this will ensure proper urls if you change url rules:
'action' => $this->createUrl('otherController/someAction'),
or same controller different action
'action' => $this->createUrl('otherAction'),
etc.
Do mean perhaps a page refresh?
Just do $this->refresh() inside your controller action.
If I defined 2 controllers, A.php and B.php, and in each controller I defined an index action,
how should I define Route::set in the bootstrap.php file?
The default route should do just fine:
Route::set('default', '(<controller>(/<action>(/<id>)))')
->defaults(array(
'controller' => 'welcome',
'action' => 'index',
));
Please read the documentation: http://kohanaframework.org/3.2/guide/kohana/routing
That default route will match both controller '/a' and controller '/b', and execute the index action if no other action is specified in the URI.
I have read the documentation and it's not completely clear when and why you would want to create a Route entry.
Basically, a Route entry is needed if you have a URL that does not conform to the normal /controller/action structure. If you have created controller A and controller B both with index actions, you don't need to add routes to bootstrap.php if you are always going to access those actions using the standard URL syntax:
http://www.example.com/A/index
http://www.example.com/B/index
You could leave off "index" since it is the default action if none is specified.
Let's say you want controller A to be the default site controller, meaning that you don't want to have to use A in the URL, you want to use the action right after the domain:
http://www.example.com/index
Then you do need a route to tell Kohana that any URL that is not matched by any routes you have created (or if you have none) should be handled by your default route. You would create this route in bootstrap.php:
Route::set('default', '(<controller>(/<action>(/<id>)))')
->defaults(array(
'controller' => 'A',
'action' => 'index'
));
This says that if a user goes to http://www.example.com, Kohana will use the index action of controller A. If the user goes to http://www.example.com/foo, then Kohana will use the foo action of controller A. Any URL that does not match any other controller will go to the A controller. If a user requests an action that A does not handle, he'll get a 404 exception.
You still have the B controller, so that will work fine without any route. If the user goes to http://www.example.com/B/index, Kohana knows about the B controller in the app so it will go to the index action there.
Your problem may be in .htaccess file in kohana folder.
I needed to change the "RewriteBase" to the Kohana folder ('base_url' from Kohana::init in bootstrap.php file), otherwise I landed in '404 - no object found'.
Then the default route should do just fine.
I'm try to create search engine friendly URLs for the pages controller, i.e. /about instead of /pages/about.
I've tried setting up the following routes (at the bottom of routes.php):
Router::connect('/*', array('controller' => 'pages', 'action' => 'display'));
and
Router::connect('/:page', array('controller' => 'pages',
'action' => 'display'), array('pass' => array('page'), 'page' => '[a-z]+'));
Both properly match /about, /support, etc. However, failed when I had a action/method pair. For example, /contact should route to PagesController->contact(). However, the above routed it to PagesController->display().
There has to be a way to accomplish this without making a specific route for each page. How can I create a route or set of routes that:
Mimics the default route behavior for
the PagesController. That is routes
to display() unless a action/method
pair exists.
Does so with search engine friendly URL. That is coming from root / not /pages.
Demonstrate both the Router::connect() and Html->link()
I have checked for examples in the CakePHP Book and viewed other questions such as CakePHP routing in pages controller. Nothing seems to satisfy the specification above.
You need to create a second route for the contact method call and put it before the more generic rule to match "everything [a-z] after /pages". Try that before your rule:
Router::connect('/contact', array('controller' => 'pages', 'action' => 'contact'));
Always keep in mind that the order of routes is important. The more generic a rule is the more will it match. So put more specific rules in front of the more generic ones.
Would like http://websites.com/users/username1 URL structure
In your app/config/routes.php file you could add:
Router::connect('/users/*', array('controller' => 'users', 'action' => 'index'));
This would route all requests to /users/ to the index action of the users controller. If you want to use a different action, just replace 'index' with the action you prefer to use.
More info is here:
http://book.cakephp.org/view/46/Routes-Configuration
I have a set of rather static pages wich I moved to the views/pages folder. The resulting *.ctp files are editable by my customer through CushyCMS (simplistic cms perfect for dummy proof editing). However CushyCMS generated preview links that obviously don't take CakePHP into account. I would like to solve this little problem with custom routing, but can't get my head around the details..
How can I dynamically connect the url http://localhost:8888/cake125/app/views/pages/test.ctp to http://localhost:8888/cake125/pages/test?
I added the following in my routes.php:
Router::connect('/pages/test.ctp', array(
'controller' => 'pages',
'action' => 'display', 'test'));
This works ok for connecting: http://localhost:8888/cake125/pages/test.ctp to http://localhost:8888/cake125/pages/test. Somehow following snibbet doesn't do the trick:
Router::connect('/app/views/pages/test.ctp', array(
'controller' => 'pages',
'action' => 'display', 'test'));
Ideally I'd like to have a single Router::connect statement which connects all /app/views/pages/*.ctp requests to the right place.
Finally I would also like to correctly handle google search results for the old version of the site. Like so:
Router::connect('/test.html', array(
'controller' => 'pages',
'action' => 'display', 'test'));
This works ok but I'd rather have anypage.html connect to /pages/anypage. Can anyone help with this?
Thanks in advance!
First, by virtue of having Cake in a subdirectory (/cake125), I think you may need to connect the /cake125/:controller/:action, rather than how you have it. Not 100%, though; Cake might be robust enough to handle that use case. If you have weird errors, I'd check that.
On with my answer:
I think you are somewhat misunderstanding how the Router class works. You connect URLs, not relative filesystem paths, using Router::connect. By default (which you may have erased, but it's pretty simple to fix), Cake will route requests to /pages/* to the PagesController::display() function, passing it one argument (the action listed in the http request).
So, to have the pages controller map /pages/one to the app/views/pages/one.ctp element, simply make sure that the following (default, i.e. Cake normally has this setup) line is in the routes config (and make sure that lines above it do not match that pattern):
Router::connect( '/pages/:action', array( 'controller' => 'pages', 'action' => 'display', :action);
This should ensure that PagesController::display( $action ) is invoked during the request, which is (I think) what you're after.
If your CMS generates preview links that you want to correctly re-route, I'd suggest adding a new route. E.g., if your CMS generates links like http://somesite.com/cms/preview/newly_edited_file, you can route it like this:
Router::connect( '/cms/preview/:action', array( 'controller' => 'pages', 'action' => 'display', :action );
For your second question: have a default rule in your routes (make it the last rule, and have it match *). It will then be configured to route all not found requests to your controller/action pair as requested. Try this:
Router::connect( '/:action', array( 'controller' => 'pages', 'action' => 'display', :action );
Major caveat this will break your existing routes. You will need to manually add an entry for each of your existing controllers (Router::connect( '/users/:action', ...etc...). If you google around you can find some clever solutions, such as having that list generated at runtime for you. But you will need to address "normal" routing, once you've added that catch-all (and make sure your catch-all is at the end of the routing file).
Also, if you want to parse URLs like /test.html, simply add a call to Router::parseExtensions(...) so that Cake will register .html as an extension for it to parse. Check the manual on that function for more info.
As others have pointed out how CakePHP Router works, I'll leave it at that.
For the second part of your question (handling old links), I'd suggest adding this to the end of your Routes list:
Router::connect( '/:page',
array (
'controller' => 'pages',
'action' => 'display',
),
array (
'pass' => array ('page'), // to pass the page as first arg to action
'page' => '.+\.html$', // to verify that it ends with .html
)
);
You'd unfortunately have to parse out the .html yourself though
How can I dynamically connect the url http://localhost:8888/cake125/app/views/pages/test.ctp to http://localhost:8888/cake125/pages/test?
Well, the thing is, you don't. :-)
What I mean by that is, you do not connect a URL to another URL. What you really do is, you make certain URLs trigger certain Controller functions (or Actions for short) which in turn may (or may not) render certain Views. By default it's all straight forward through naming conventions. The URL /foo/bar triggers the Controller Foo's Action bar and renders the View /views/foo/bar.ctp.
The PagesController is already a special case. The URL /pages/foo triggers the Controller Pages's Action display, passes it the parameter foo, which renders the View /views/pages/foo.ctp. Notice the difference in which Action is triggered.
Since there are a lot of steps inbetween, it's not a given that a certain URL corresponds to a particular file on the hard disk. The URL /foo/bar might trigger Controller Baz' Action doh which renders the View /views/narf/glob.ctp.
This makes translating http://localhost:8888/cake125/app/views/pages/test.ctp to render the file /views/pages/test.ctp somewhere between an uncertainty and a pain in the rear.
Edit:
Having said that, the particular problem in your case is that the base URL is http://localhost:8888/cake125/app/. You can invoke a Cake app from http://localhost:8888/cake125/, http://localhost:8888/cake125/app/ or http://localhost:8888/cake125/app/webroot. All three URLs will be handled by the same file cake125/app/webroot/index.php, if you use one of the shorter URLs the request will be "forwarded" (rewritten) via .htaccess rules.
So the Route you're trying to connect, the Route that Cake sees, is actually /views/pages/test.ctp.
Actually, my mistake, this might not be the problem, but it depends on your .htaccess files and server configuration.
It doesn't seem to make much sense in a CMS though, since every newly created page would need its own rule. So I'd recommend against trying to do so and rather hack Cushy to properly construct URLs using the Cake HtmlHelper or Router::url(). Failing that, connect all URLs with a catch-all rule to some Action, parse the URL there and render the correct View "manually".
Alternatively, use .htaccess files and rewrite rules to actually rewrite the URL into a normal Cake URL, so Cake doesn't have to worry about it. As said above though, this can be very fragile.