I'm using this plugin to create slug-based URL's on a CakePHP 2 web application: https://github.com/josegonzalez/cakephp-dynamic-route
The documentation suggests that you would call a Cake controller like so:
posts/view?id=45
My URL's currently work as Cake's default behaviour. So using the example above posts/view/45 works but posts/view?id=45 does not.
When I call URL's as per the example I get a 404 error.
My functions are written like so (e.g. in PostsController.php):
public function view($id) {
// logic to load post by ID
// ...
}
There is almost no documentaiton for the above plugin. Has anyone used it or know where I'm going wrong? It seems you cannot pass a GET variable such as 'id' to the 'view' function, without re-factoring the code inside it to accept passed parameters?
The solution appears to be that some of the controller functions needed to be re-written to accept GET style parameters.
In the documentation a "spec" field looks like this:
posts/view?id=45
In a regular CakePHP application the route for that would be like this: posts/view/45
The plugin simply doesn't work if you put the second style of route (posts/view/45) into the "spec" field.
So the answer is the "spec" fields must be like so:
posts/view?id=45 and then your controller functions have to be re-written, e.g.
public function view($id) {
if (isset($this->request->params['id'])) {
$id = $this->request->params['id'];
}
}
Doing this means that it will work with a parameter (view?id=45) or a standard Cake call (view/45).
Please note this has nothing to do with the "slug" aspect of the plugin - the "slug" can be anything, as per the documentation examples: /why-isnt-this-pup-asleep or /manchester/cakephp-developers-dance-to-beyonce. The original question was asking if there was a way to map a "spec" given in the documentation to a Cake controller function without having to modify it like I have above. The answer seems to be no, you have to modify them!
Related
I'm attempting to create a custom display in yii2 framework using this code in my site controller:
/******/
public function actionChartDisplay()
{
return $this->render('chartDisplay');
}
for testing purposes I pasted the form name in my actionAbout function as a parameter to the render function in it. It worked with this:
public function actionAbout()
{
return $this->render('chartDisplay');
}
But I need to create many custom views in yii2 and this won't be a solution.
This is the error I get
I'm curious as to why it is. Since I was following this tutorial and came across this weird behaviour.
My 'chartDisplay.php' file is merely a "hello world" that does work with the action about function.
in yii2, the controllers and actions with multiple words, that are marked by capital letters are divided by - in your request, so in your case the route would be some/chart-display
Apparently as #SmartCoder pointed out it was an error on how Yii2 Handles the action functions in its controller however I didn't mark his answer as the solution right away because implementing it resulted in an error. So aside from that I'm posting the way I solved it.
So instead of using chart-display I simply changed it for "charts" like this:
public function actionCharts(){
return $this->render('charts');
}
Changed the name of my file so it fits to charts.php and it worked.
This seems like it should be a simple task. I need the current URL from a function within the Controller. This function can be called from multiple actions, and the end goal is to set a form's action attribute. (Side note: It appears IE does not send an ajax request if the URL starts with '#').
I feel like my google-fu is off today because I could not find a good way to do this Zend Framework 2. I have this line currently, but it feels very bulky:
$this->url()->fromRoute(
$this->getServiceLocator()
->get('Application')
->getMvcEvent()
->getRouteMatch()
->getMatchedRouteName()
);
Couldn't you just get the URI from the request object:
$this->getRequest()->getUriString()
Provided your controller extends Zend\Mvc\Controller\AbstractActionController.
Note: This would output the entire URL, like so:
http://example.com/en/path/subpath/finalpath?test=example
If your request route is like this:
http://example.com/en/path/subpath/finalpath?test=example
And You want only this:
/en/path/subpath/finalpath?test=example
You can simply do : $this->getRequest()->getRequestUri()
To specify my Request object is an instance of
\ZF\ContentNegotiation\Request
I have a route like this:
Route::get('demo/{system?}', 'MonitorController#demo');
I am using it like so because I would like my url to look like so:
mysite.com/demo/spain-system
Where spain-system will be the variable I need to get.
Right now, I'm getting it like this:
public function demo($systemName = null){
}
But I would like to be able to access to it as if it were a URL parameter with Input::get('system') so I can access to it from other methods or even from other controllers such as BaseController.php.
Is there any way to achieve this?
I've played around with Route::input('system') but then it doesn't work when I pass it as a get parameter (in other Ajax calls and so on)
Update
In PHP we can get URL params by using the $_GET function and laravel provides the function Input::get() to do so as well.
If there were no routes in laravel, I would make use of .htaccess rewrite rules to change this:
mysite.com/demo/?system=spain-system
To this:
mysite.com/demo/spain-system
And I could still retrieve the variable system as a GET parameter by using $_GET["system"].
That's kind of what I would expect of laravel, but it seems it is just treating it as the parameter of the demo method and not really as a URL variable.
Is there any way to keep treating it as a URL variable and at the same time use it in a pretty URL without the ?system= ?
So you actually just want to get an url like this? mysite.com/demo/spain-system instead of mysite.com/demo/?system=spain-system? Laravel provides that by default?
Look, When you want to get the router variable {system?} to be accesible you'll need to do this:
In your router:
Route::get('demo/{system}', 'MonitorController#demo');
Then you have an controller where this noods to stand in:
public function demo($system)
{
//your further system
//You are be able to access the $system variable
echo $system; //just to show the idea of it.
}
When you now go to to localhost/demo/a-system-name/, You'll see a blank page with a-system-name.
Hope this helps, because your question is abit unclear.
I am currently working on CMS for a client, and I am going to be using Codeigniter to build on top of, it is only a quick project so I am not looking for a robust solution.
To create pages, I am getting to save the page details and the pull the correct page, based on the slug matching the slug in the mysql table.
My question is however, for this to work, I have to pass this slug from the URL the controller then to the model, this means that I also have too have the controller in the URL which I do not want is it possible to remove the controller from the URL with routes?
so
/page/our-story
becomes
/our-story
Is this possible
I would recommend to do it this way.
Let's say that you have : controller "page" / Method "show"
$route['page/show/:any'] = "$1";
or method is index which I don't recommend, and if you have something like news, add the following.
$route['news/show/:any'] = "news/$1";
That's it.
Yes, certainly. I just recently built a Codeigniter driven CMS myself. The whole purpose of routes is to change how your urls look and function. It helps you break away from the controller/function/argument/argument paradigm and lets you choose how you want your url's to look like.
Create a pages controller in your controllers directory
Place a _remap function inside of it to catch all requests to the controller
If you are using the latest version of CI 2.0 from Bitbucket, then in your routes.php file you can put this at the bottom of the file: $routes['404_override'] = "pages"; and then all calls to controllers that don't exist will be sent to your controller and you then can check for the presence of URL chunks. You should also make pages your default controller value as well.
See my answer for a similar question here from a few months back for example code and working code that I use in my Codeigniter CMS.
Here's the code I used in a recent project to achieve this. I borrowed it from somewhere; can't remember where.
function _remap($method)
{
$param_offset = 2;
// Default to index
if ( ! method_exists($this, $method))
{
// We need one more param
$param_offset = 1;
$method = 'index';
}
// Since all we get is $method, load up everything else in the URI
$params = array_slice($this->uri->rsegment_array(), $param_offset);
// Call the determined method with all params
call_user_func_array(array($this, $method), $params);
}
Then, my index function is where you would put your page function.
Rather than using controller/action/key1/value1/key2/value2 as my URL, I'd like to use controller/action/value1/value2. I think I could do this by defining a custom route in my Bootstrap class, but I want my entire application to behave this way, so adding a custom route for each action is out of the question.
Is this possible? If so, how would I then access valueN? I'd like to be able to define the parameters in my action method's signature. e.x.:
// PostsController.php
public function view($postID) {
echo 'post ID: ' . $postID;
}
I'm using Zend Framework 1.9.3
Thanks!
While I don't think it's possible with the current router to allow N values (a fixed number would work) you could write a custom router that would do it for you.
I would question this approach, however, and suggest that actually listing all of your routes won't take long and will be easier in the long run. A route designed as you've suggested would mean that either your named parameters are always in the same order, i.e.
/controller/action/id/title/colour
or that they are almost anonymous
/controller/action/value1/value2/value3
With code like
$this->getRequest()->getParam('value2'); //fairly meaningless
Does it have to be N or can you say some finite value? For instance can you imagine that you'll never need more than say 5 params? If so you can set up a route:
/:controller/:action/:param0/:param1/:param2/:param3/:param4
Which will work even if you don't specify all 5 params for every action. If you ever need 6 somewhere else you can just add another /:paramN onto the route.
Another solution I've worked with before is to write a plugin which parses the REQUEST_URI and puts all the extra params in the request object in the dispatchLoopStartup() method. I like the first method better as it makes it more obvious where the params are coming from.