I am trying to set up Zend Framework 2 with multiple site specific modules. Each module configuration includes its own uniquely named literal path route. However, these routes are always ignored in favor of the "home" route in the application module. The URL points to the physical location of the index.php file for ZF2.
So, URL: localhost/zend/module/name/public/
config:
'routes' => array(
'moduleByPath' => array(
'type' => 'Literal',
'options' => array(
'route' => '/zend/module/name/public/'
),
'may_terminate' => true,
'child_routes' => $childRoutes,
),
),
But, I get matched to "home" as defined in the default Application. If I change the home route from '/' to '/doesntexist/' I get an error that the path doesn't match routing.
The module is being included correctly, as I can add a route to match by domain and everything loads correctly.
ZF2 'Literal' routes do not match up to physical directories, it just means a literal URI, rather than a 'Segment' URI for example that can take parameters like :action or :controller etc.
To make that route work in the example, you would need to move index.php up to the root /, ensure .htaccess is working correctly and remove the 'zend' physical directory and all subdirectories completely.
This will then cause ZF2 to map the literal URI /zend/module/name/public/ to that route 'moduleByPath', and process child_routes where necessary.
Also, normally for Literal routes you would declare a default controller and action that should load for this URI like this:
<?php
return [
'routes' => [
'api' => [
'type' => 'Literal',
'options' => [
'route' => '/api',
'defaults' => [
'controller' => 'api',
'action' => 'index',
],
],
'may_terminate' => true,
'child_routes' => [
// ...
]
]
]
];
For example. Ensuring you have the controller 'api' declared as invokeable in the config too:
<?php
// ...
'controllers' => [
'invokables' => [
'api' => 'MoudleName\Controller\ApiController'
// ... other invokables
]
]
Hope this helps, let me know if i'm not making sense :) Happy coding
Related
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.
I have the following in my application module config:
'controllers' => [
'factories' => [
Application\Controller\IndexController::class => Application\Controller\IndexControllerFactory::class
],
],
this works fine. now im my serve module i have pretty much the same:
'controllers' => array(
/**
'invokables' => array(
'Serve\Controller\Index' => 'Serve\Controller\IndexController',
),
*/
'factories' => array(
Controller\IndexController::class => Serve\Controller\IndexControllerFactory::class
)
),
when i load the homepage i access through an api the serve controller. when doing so i get this problem on the homepage:
Serve\Controller\Index (resolves to invalid controller class or alias: Serve\Controller\Index)
like i said im accessing the serve controller through an api so it might be a setup issue when requesting through the system as an api.
Whats interesting is when i do this it works:
'controllers'=>array(
'invokables' => array(
'Serve\Controller\Index' => 'Serve\Controller\IndexController',
)),
not sure whats wrong here
UPDATE:
This seems to work:
'factories' => array(
'Serve\Controller\Index' => IndexControllerFactory::class
)
however id like to use ::class syntax
The problem lies within your route config as you map to the controller: Serve\Controller\Index but you either never registered that controller with that specific key within your module.config or you are using the wrong value for the key "controller" within your route as you specified the FQCN within your controller mapping.
// module.config
'aliases' => [
'Serve\Controller\Index' => Serve\Controller\IndexController:class,
],
'factories' => [
Serve\Controller\IndexController:class => Serve\Controller\IndexControllerFactory::class,
],
Or within your route configs don't use the Serve\Controller\Index but use the FQCN, so that it uses the Factory directly instead of the alias you've set up. Like:
// route.config
'serve' => [
'type' => 'literal',
'options' => [
'route' => '/serve',
'defaults' => [
'controller' => Serve\Controller\IndexController::class,
'action' => 'index',
],
],
],
I keep mapping my classes in the factory mapping with the FQCN and add aliases if I want to call them by another name. So you are now able to either use the FQCN or any of its aliases, like: Serve\Controller\Index
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'm just starting off with Zend Framework, and I'm not quite sure what I'm doing wrong with the URI routing.
I'm starting with an initial Zend Framework project in Zend Studio based in my htdocs folder (I'm using Zend Server as well on Windows 7). Everything up to there seems to be working fine getting the index page up (it's running out of the /public/ subdirectory).
But when I try to add a module though, in this case called Users with a controller called Index, and following the instructions in getting that configured, I'm not sure what I should be putting in the URI to get it to route to it's view. I've tried just about every configuration of URI combinations that I can think of (localhost:80/public/users, localhost:80/public/users/index, localhost:80/users, etc)
I'm not getting a routing error, but just a plain 404 page.
Do I need to set the public folder as the root? Or is there something else I need to do to get the routing to work?
~edit in response to bitWorking
It looks like it does automatically add it to the application.config.php. But here is the module.config.php of the Users module
'router' => array(
'routes' => array(
'users' => array(
'type' => 'Literal',
'options' => array(
// Change this to something specific to your module
'route' => '/index',
'defaults' => array(
// Change this value to reflect the namespace in which
// the controllers for your module are found
'__NAMESPACE__' => 'Users\Controller',
'controller' => 'Index',
'action' => 'index',
),
),
'may_terminate' => true,
'child_routes' => array(
// This route is a sane default when developing a module;
// as you solidify the routes for your module, however,
// you may want to remove it and replace it with more
// specific routes.
'default' => array(
'type' => 'Segment',
'options' => array(
'route' => '/[:controller[/:action]]',
'constraints' => array(
'controller' => '[a-zA-Z][a-zA-Z0-9_-]*',
'action' => '[a-zA-Z][a-zA-Z0-9_-]*',
),
'defaults' => array(
),
),
),
),
),
),
),
Now I do see where it's guiding you to customize the routes. I've experimented with this as well, but still am not sure what I should set them to. Much closer though.
If you want to call the Index controller in your Users module with /users you have to name the route accordingly:
...
'users' => array(
'type' => 'Literal',
'options' => array(
// Change this to something specific to your module
'route' => '/users',
---------
...
Else please control the application.config.php. It should look like:
return array(
'modules' => array(
'Application',
'Users',
),
...
So the Url's should look like:
localhost/public/users -> Users/Controller/IndexController/indexAction
localhost/public/users/foo -> Users/Controller/FooController/indexAction
localhost/public/users/foo/bar -> Users/Controller/FooController/barAction
We're using Zend Framework 2 and use toRoute within our controllers to redirect to various locations, for example $this->redirect()->toRoute('home');.
Is there anyway to have this redirect to https instead of http using this method or an alternative method?
Thank you!
In order to use https in your route you need to use the Zend\Mvc\Router\Http\Scheme router. Specifying the configuration for such route is not very different from the other routes. You need to specify the route type as Scheme and add an option 'scheme' => 'https' in your router configuration in module.config.php.
Here is an example:
return array(
'router' => array(
'routes' => array(
'routename' => array(
'type' => 'Scheme', // <- This is important
'options' => array(
'route' => '/url',
'scheme' => 'https', // <- and this.
'defaults' => array(
'__NAMESPACE__' => 'MdlNamespace\Controller',
'controller' => 'Index',
'action' => 'someAction',
),
),
),
// the rest of the routes
),
),
// the rest of the module config
);
If you have the route routename configured like above, this: $this->redirect()->toRoute('routename'); will work.
See this for reference to the ZF2's manual.
Hope this helps :)
Stoyan