I want to write new route for RSS-View. The call /news/index.rss must open the RSS-Feed, but it open wrong methode.
routes.php
Router::parseExtensions('rss');
...
// don't work
Router::connect('/news/index.rss', array('controller' => 'news', 'action' => 'index'));
...
// open News:indexForPage()
Router::connect('/news/indexForPage/*', array('controller' => 'news', 'action' => 'indexForPage'));
...
// List width pagignation (News:index())
Router::connect('/news/*/:slug/:page',
array(
'controller' => 'news',
'action' => 'index'
),
array(
'competence_id'=>'[a-z,0-9,A-Z,\-]+',
'page'=>'[a-z,0-9,A-Z,\-]+'
)
);
...
// After call '/news/{Title-of-the-Article}-{ID}', it open News:view(ID)
Router::connect('/news/**', array('controller' => 'news', 'action' => 'view'));
That are all rules width "/news".
And wenn I call in browser "localhost/news/index.rss", it open News:view(), but not News:index(). If I deactivate the last line, it works, but I need this line.
How can I correct it?
You need to add 'ext' => 'rss' to your route as you are using Router::parseExtensions('rss');:-
Router::connect(
'/news/index.rss',
array('controller' => 'news', 'action' => 'index', 'ext' => 'rss')
);
I accepted the answer from drmonkeyninja quickly and not tested all functions.
I'm pleased width actually functions, but it is not perfect.
What I want, what I have, and what works:
localhost/news/index.rss – It opens RSS-Feed. It works.
localhost/news/, localhost/news/index – It opens all news sorted by publish date width pagignation (AJAX). It works.
localhost/news/{CATEGORY-ID} – It must open news filtered by CATEGORY-ID (integer) sorted by publish date width pagignation (AJAX). It don't work. (It opens localhost/news/view/{NEWS-ID}, see next point.) But it is not important, see "my alternative solution".
localhost/news/{NEWS-TITLE}-{NEWS-ID}, localhost/news/view/{NEWS-ID} – It opens the content of the one news width id={NEWS-ID}. It works. Where {NEWS-TITLE} is string (characters, numbers and '-'), and {NEWS-ID} is integer.
My code:
routes.php
// RSS-Feed. See point 1.
Router::connect('/news/index.rss', array('controller' => 'news', 'action' => 'index', 'ext' => 'rss'));
// See point 2. localhost/news/index
Router::connect('/news/index', array('controller' => 'news', 'action' => 'index'));
// It is for other methode. It works, and it isn't interesting.
Router::connect('/news/indexForPage/*', array('controller' => 'news', 'action' => 'indexForPage'));
// It is easy. localhost/news/view/{NEWS-ID} See point 4.
Router::connect('/news/view/*', array('controller' => 'news', 'action' => 'view'));
// localhost/news/{NEWS-TITLE}-{NEWS-ID} See point 4.
Router::connect('/news/*', array('controller' => 'news', 'action' => 'view'));
// My alternative solution for point 3. (e.g. localhost/breaking-news/3 It works fine with filter and AJAX-pagignation.)
Router::connect('/breaking-news/*/:slug/:page',
array(
'controller' => 'news',
'action' => 'index'
),
array(
'competence_id'=>'[0-9]+',
'page'=>'[a-z,0-9,A-Z,\-]+'
)
);
NewsController.php
class NewsController extends AppController {
public $helpers = array('Paginator');
public $components = array('RequestHandler', 'Paginator');
/**
* See points 1-3.
* #param string $competence_id
*/
public function index($competence_id = NULL) {...}
/**
* It isn't interesting.
* #param int $count
* #param int $sector
*/
public function indexForPage($count = NULL, $sector = NULL) {...}
/**
* See point 4.
* #param string $id
*/
public function view($id = NULL) {...}
}
Points for betterment are welcome:
New rooles in routes.php for cases localhost/news/{integer} (point 3) and localhost/news/{string}-{integer} (point 4)
Alternative solutions
Related
I have a multi language website, but when I don't do a redirect with a setFlash, it deletes the language from the url. Example: if the contactform doesn't validate, it just does a setFlash without the redirect, so that user input data is not lost. But it does refresh the page and deletes the language part from my url. This does not happen when I do a redirect after my setFlash, because I give the language param with the redirect. Work flow:
I start on the page website.com/eng/contact (notice the language part). I fill in the contact form and fill in all required inputs. It redirects me to website.com/eng/contact/send. That's great and what I want. But when I don't give an valid email adres for example, it display an error (great), but the url has changed to website.com/forms/contact (notice the missing language part, and it doesn't use my routes). What am I doing wrong? My code:
Formscontroller.php
public function contact() {
if ($this->request->is('post')) {
$this->Form->set($this->request->data);
if ($this->Form->validates()) {
if($this->Form->save($this->request->data)){
$this->redirect(array('controller' => 'forms', 'action' => 'contact_success', 'language' => $this->Session->read('Config.language')));
} else {
$this->Session->setFlash(__('Er ging iets mis met het versturen van uw contactformulier, probeer het opnieuw.'), 'flash_error');
}
} else {
$this->Session->setFlash(__('Niet alle verplichte velden zijn ingevuld.'), 'flash_error');
}
}
}
routes.php
Router::connect('/:language/pages/*', array('controller' => 'pages', 'action' => 'display'));
Router::connect('/:language/contact', array('controller' => 'forms', 'action' => 'contact'), array('language' => 'ned|eng'));
Router::connect('/:language/contact/verzonden', array('controller' => 'forms', 'action' => 'contact_success'), array('language' => 'ned'));
Router::connect('/:language/contact/send', array('controller' => 'forms', 'action' => 'contact_success'), array('language' => 'eng'));
Router::connect('/', array('controller' => 'pages', 'action' => 'display', 'home'));
Router::connect('/:language', array('controller' => 'pages', 'action' => 'display', 'home'), array('language' => 'eng|ned'));
Router::connect('/:language/:controller/:action/*', array(), array('language' => '[a-z]{3}'));
CakePlugin::routes();
require CAKE . 'Config' . DS . 'routes.php';
I was looking in the wrong direction for my problem. As ndm points out in his comment on my question, it had to do with the action of my form, it didn't have the language part in it. So thanks to ndm for pointing me in the right direction!
Using this code:
$sitemap = 4;
$link = $this->Html->link( $sitemap . '.xml', null,
array('plugin' => $this->request->plugin,
'controller' => $this->request->controller,
'action' => 'view',
'admin' => false));
I expect to get a link that looks like this:
http://www.domain.com/vreb_listings/vreb_listing_feeds/view/4.xml
Instead, I get this:
/admin/vreb_listings/vreb_listing_feeds/4.xml
What gives? The action => view is having no effect, as view doesn't show up in the url, and the admin => false isn't working either, as admin does show up. This code is in the admin area.
I haven't even looked up how to include the full domain path in the url. Also, I want the title text to be the same as the url.
According to docs, the second parameter is the url one, so in your code it should be
$link = $this->Html->link( $sitemap . '.xml',
array('plugin' => $this->request->plugin,
'controller' => $this->request->controller,
'action' => 'view',
'admin' => false));
(remove the null second parameter)
Oh, and for title text, that is the third parameter, so
$link = $this->Html->link( $sitemap . '.xml',
array('plugin' => $this->request->plugin,
'controller' => $this->request->controller,
'action' => 'view',
'admin' => false),
array('title' => $sitemap.'.xml'));
should do the trick
I hope you can forgive my bad english, I hate auto translating services... So I write by my own. xD
I am working in cakePHP 2.1, but the code is not mine. For some reason, when I create a new view with its correct controller created, the system redirectsme to the root. So, I cannot create a new view. Of course, the view exist in the controller becouse I add it.
For example, I add this code in cake/Controller/DocumentsController.php:
function add_pago() {
//I code for food.
}
And I create a new file called cake/Views/Documents/add_pago.ctp with this random code after the php tag:
echo "hello, world!";
There's no beforeFilter() function in DocumentsController.php. In AppController.php, the beforeFilter function is shown bellow:
public function beforeFilter() {
//Configure AuthComponent
//$this->Auth->allow('display');
$this->Auth->loginAction = array('controller' => 'users', 'action' => 'login');
$this->Auth->logoutRedirect = array('controller' => 'users', 'action' => 'login');
$this->Auth->loginRedirect = array('controller' => 'pages', 'action' => 'display', 'home');
if(!empty($this->data)) array_walk_recursive($this->data, array($this, '__whitespace'));
}
Simple ACL is active. The programmer can't remeber what he did to get this behavior. And I can't figure how to fix this.
Do you have any suggestion to find where in the code is programmed this?
Use $this->Auth->allow('add_pago'); in your beforeFilter callback.
public function beforeFilter() {
//Configure AuthComponent
//$this->Auth->allow('display');
$this->Auth->loginAction = array('controller' => 'users', 'action' => 'login');
$this->Auth->logoutRedirect = array('controller' => 'users', 'action' => 'login');
$this->Auth->loginRedirect = array('controller' => 'pages', 'action' => 'display', 'home');
if(!empty($this->data)) array_walk_recursive($this->data, array($this, '__whitespace'));
$this->Auth->allow('add_pago');
parent::beforeFilter();
}
I'm working Cake 2.1.3, and the routes.php file, everything worked fine except the login management, for example I want my url be as follows:
http://mysite.com/companyx/users/login
where companyx is the slug, however when you run that url in the browser is as follows:
http://mysite.com/users/login
In this file routes.php I have defined as follows:
Router::connect(
'/:slug/users/login', // E.g. /companyx/users/login
array('controller' => 'users', 'action' => 'login'), array(
// order matters
'pass' => array('slug')
)
);
With other controllers I have no problems such as:
Router::connect(
'/:slug/users', // E.g. /companyx/users
array('controller' => 'users', 'action' => 'index'), array(
// order matters
'pass' => array('slug')
)
);
Best Regards ;)
CakePHP has a default login action defined in the AuthComponent. (line 171)
/**
* A URL (defined as a string or array) to the controller action that handles
* logins. Defaults to `/users/login`
*
* #var mixed
*/
public $loginAction = array(
'controller' => 'users',
'action' => 'login',
'plugin' => null
);
You can override this action with the beforeFilter in your own UsersController.
thanks for you answer. I solved this case this way:
public function beforeFilter() {
parent::beforeFilter();
if (!$this->request->is('post')) {
$this->Auth->loginAction = 'this is:slug/users/login/';
}
}
Where "this is slug", should be the slug.
Best Regards.
I'm using different routing tables for every language, and I have wrote action which change language and redirects to the same page but in target language (and target url).
The main problem is that my action is way too complicated - how can I make it simple?
It should change language and redirect to new url (in target language).
In short: We had random valid cake url in one language and we had to translate it to adequate url in another language.
My routing table:
if( 'en' == Configure::read('Config.language') ) {
Router::connect('/help', array('controller' => 'pages', 'action' => 'display', 'help') );
} else {
Router::connect('/pomoc', array('controller' => 'pages', 'action' => 'display', 'help') );
}
Action changing language:
function lang($lang) {
// getting previous url table
$url = $this->referer();
$url = Router::parse($url);
// changing language
if( in_array($lang, Configure::read('Languages.valid') ) ) {
$this->Session->write('Language', $lang);
Configure::write('Config.language', $lang);
}
// saving base params
$requestInfo = array(Router::getParams(), Router::getPaths());
// reload routing table
Router::reload();
include(CONFIGS.'routes.php');
// restore base params
Router::setRequestInfo($requestInfo);
// fix for 'pass' params
if(!empty($url['pass']) && is_array($url['pass'])) {
$url = array_merge($url, $url['pass']);
unset($url['pass']);
}
$this->redirect($url);
}
About 'pass' key in url table:
/pages/display/help
after Router::parse(), parameter is extracted:
pass => array(
0 => 'help'
)
and later return value from Router::url() look like that:
/pages/display/pass:Array
so I have to fix it by merging 'pass' value with whole array and removing key
I have my routes.php like this
Configure::write('Config.language', $_SESSION['lang']);
Router::connect(__('/help',true), array('controller' => 'pages', 'action' => 'display', 'help') );
so I use the __() to translate the url. It seaches the translation in the po files. And in your lang() function, after changing the Session to the current lang, all you need to do is:
$this->redirect(__('/help'));
Hope this helps
I know it is too late to answer that, but for those who experience the similar needs:
In routes.php p1 identifies the static page (same for all languages), could be any string that uniquely identifies the page.
Router::connect('/:language/p1/:translation', array(
'controller' => 'pages',
'action' => 'display',
'help',
'options' => array('language' => '[a-zA-Z]{2}')
) );
In your view
$this->Html->link('Click me', array(
'language' => Configure::read('Config.language'),
'controller' => 'pages',
'action' => 'display',
'help',
'translation' => __('help') // could be any string in fact
));
will generate link to /en/p1/help in English, else to /xx/p1/pomoc.
Injection of language parameter into every link could be done in AppHelper::url() instead of providing it in every link occurence.
If you want to redirect in controller:
$this->redirect(array(
'language' => Configure::read('Config.language'),
'controller' => 'pages',
'action' => 'display',
'help',
'translation' => __('help')
));