This project has been ported over manually from Zend Frame work 2 to Laminas. The issue here is that the module.config.php has been set up in the same way as other modules that are working. However I am encountering this error. I have checked the usually culprits such as files spelling or missing, no other modules are using the same route name. Is there another part of Laminas that would affect the view manager?
The modul.config.php setup is below.
'''
namespace ProjectTaskDocument;
use Laminas\Router\Http\Segment;
return [
'router' => [
'routes' => [
'project-task-document' => [
'type' => Segment::class,
'options' => [
'route' => '/task-document[/:action][/:id]',
'constraints' => [
'action' => 'index|add|download|view-all|delete'
],
'defaults' => [
'controller' => Controller\ProjectTaskDocumentController::class,
'action' => 'index'
]
]
]
]
],
'view_manager' => [
'template_path_stack' => [
'ProjectTaskDocument' => __DIR__ . '/../view'
],
]
];
'''
The module folder structure
Realised my mistake, during my port process another module was using the same Key identifier for the view_manager->template_path_stack. I feel pretty damn dumb for missing this.
How can I defined two same URI that have two difference method to be called ?
For example :
'owners/<user_id:\d+>/pets' => 'pets/index', //using GET
'owners/<user_id:\d+>/pets' => 'pets/create',//using POST
I try this code below :
'GET owners/<user_id:\d+>/pets' => 'pets/index',
'POST owners/<user_id:\d+>/pets' => 'pets/create',
but my problem is that if I have this code It always display 404 not found instead of 405?
Note that I already added this on my behaviors :
'verbs' => [
'class' => VerbFilter::className(),
'actions' => [
'index' => ['get'],
'create' => ['post'],
],
],
I would try this (in this order):
'POST owners/<user_id:\d+>/pets' => 'pets/create',
'owners/<user_id:\d+>/pets' => 'pets/index',
Is there any solution to create this URL in Zend and get more URL parts as 1 parameter?
Ex.: /someApp/someFolder/Separator/Need/This/As/One/param/
and I need "Need/This/As/One/param" as 1 parameter...
My basic route is
"someApp/someFolder/Separator/:path/"
, I've tried something like
".../:path/*"
,... but nothing works ok. There will be no other param on the end of URL so it should be ok.
It get string after site/. For example: site/Need/This/As/One/param. variable path will have string Need/This/As/One/param
'type' => 'Segment',
'options' => [
'route' => 'site/:path[/]'
'defaults' => [...],
'constraints' => [
'path' => '.+',
]
]
]
My main router goes like this (simplified):
'router' => [
'routes' => [
'blog' => [
'type' => 'regex',
'options' => [
'regex' => "/(?<language>[a-z]{2})?",
'spec' => "/%language%",
'defaults' => [
'controller' => 'Blog\Controller\Posts',
'action' => 'index'
],
],
'may_terminate' => true,
'child_routes' => [
// [...]
'add_post' => [
'type' => 'literal',
'options' => [
'route' => '/admin/post/add',
'defaults' => [
'controller' => 'Blog\Controller\Posts',
'action' => 'add'
]
]
], // end add post
] // end child routes
] // end blog route (main route)
] // end routes
] // end Router
And in the template displayed on "/en/admin/post/add" I have a call to $this->url(), that ends up printing /%language%/admin/post/add.
I have the language code available on $language on my template, and
I'd like to pass it on to url() so it properly constructs the the url using the spec.
Also, I'd like, if possible, not to specify the name of the route on my call to url(), so it uses the default one for $this.
How would I go around to accomplish this?
Thanks and regards
You could use a segment route instead of a regex one and then use
$this->getHelperPluginManager()->getServiceLocator()->get('request')->getUri()->getPath();
in your view to print the actual route it's been used
While #marcosh answer works, since then I've found a simpler solution:
$this->url($this->route, ['language' => $language]);
Will output what I want. Seems clearer to me.
I am trying to use Yii 2 routing for REST API.
Following tutorial at http://www.yiiframework.com/doc-2.0/guide-rest-routing.html, I have already defined (with success) a lot of rule for API entry point like so :
'urlManager' => [
'enablePrettyUrl' => true,
'enableStrictParsing' => true,
'showScriptName' => false,
'rules' => [
[
'class' => 'yii\rest\UrlRule',
'controller' => 'user'
],
],
]
Such a rule defines :
GET /users (list users)
GET /users/123 (show detail of user 123)
Now, my users have games. So I'd like to have urls :
GET /users/123/games (list games of user 123)
GET /users/123/games/864 (details of game 864 for user 123 - such as his scores)
I tried defining my new entry point (withhout success) like so:
'rules' => [
... previous rules ...,
[
'class' => 'yii\rest\UrlRule',
'controller' => [
'game'
],
'tokens' => [
'{userid}' => '<userid:\\d>',
'{gameid}' => '<gameid:\\d>',
],
'patterns' => [
'GET,HEAD /users/{userid}/games' => 'index',
'GET,HEAD /users/{userid}/games/{gameid}' => 'view',
]
]
]
This definition seems wrong because I get a 404 Page not found error.
How should I define my new url routes ?
I would like to use an equivalent format for my definitions, extending 'yii\rest\UrlRule'
I am not sure if this is even possible, the tutorial not mentionning this case.
So I figured out how to use more complex rules.
First, the solution, then the explanation.
Here is the solution:
'rules' => [
... previous rules ...,
[
'class' => 'yii\rest\UrlRule',
'controller' => 'game',
'prefix' => '/users/<userid:\\d+>',
'tokens' => [
'{gameid}' => '<gameid:\\d+>',
],
'patterns' => [
'GET,HEAD' => 'index',
'GET,HEAD {gameid}' => 'view',
]
]
]
And now the explanation:
First my userid / gameid attributes were badly defined. There was a missing "+" after "\d"
The controller seems to be automatically added as a prefix to the patterns. So you have to define both a controller and a prefix (that will be added before the controller).
Parameters in the prefix does not seem to be parsed to find tokens. So I wrote directly the regexp in the prefix instead of adding "userid" as a token.
Finally, there are various "/" automatically added during concatenation of "prefix/controller/pattern" so you don't have to write one.
Do not forget the pluralization rule too ! "game" is singular" but valid urls will be
/users/123/games
/users/123/games/789
Hope it will help.
I think there´s a simple solutions, please try this:
'rules' => [
...
'/users/<userId:\\d+>/games' => 'game/index' ,
'/users/<userId:\\d+>/games/<gameId:\\d+>' => 'game/view' ,
....
];
Just use yii2-nested-rest
It provides REST API for MANY-to-MANY relations in Yii2 framework.
Hope comments will make the magic more understandable:
'rules' => [
// this usual rule for base Yii2 rest usage
['class' => 'yii\rest\UrlRule', 'controller' => ['sitecomponent' ,'sitepage' , 'sitedomain'], 'pluralize'=>false
],
// then rules for yii2-nested-rest
[
// url sitepage/NNN/sitecomponent[/MMM]
// ^^^^^^^^^ ^^^^^^^^^^^^
// resourceName model-endpoint
'class' => 'tunecino\nestedrest\UrlRule',
'modelClass' => 'app\models\SitePage',
'resourceName' => 'sitepage',
'relations' => ['components' => ['sitecomponent'=>'sitecomponent'] ],
// ^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^ ^^^^^^^^^^^
// relation name url-endpoint controller]
// defined in model SitePage model-endpoint with Actions from nested
],
[
// cross url sitecomponent/NNN/sitepage[/MMM]
'class' => 'tunecino\nestedrest\UrlRule',
'modelClass' => 'app\models\SiteComponent',
'resourceName' => 'sitecomponent',
'relations' => ['pages' => ['sitepage' => 'sitepage'] ],
// ^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^ ^^^^^^^^^
// relation name url-endpoint controller
// from model SiteComponent model-endpoint with Actions from nested
],
],
GET xx.com/v2/publication/12/p/34
[
'class' => 'yii\rest\UrlRule',
'pluralize' => false,//controller是否复数
'controller' => 'v2/publication',//此处一定要加上v2
'tokens' => [
'{id}' => '<id:\\d[\\d,]*>',
'{phase}' => '<phase:\\d[\\d,]*>',
],
// 通过extraPatterns和tokens来实现多个参数传递
'extraPatterns' => [
'GET,HEAD {id}/p/{phase}' => 'phase',
],
],
IN ACTION
public function actionPhase($id, $phase){}