I have experience with php but i'm new to the zend frameworks. Could some one please give me some leads as to how I can get a site to work ie- www.facebook.com/nathandoe/photos
.
Using controllers how can i create a function that accepts different names and direct it that page ?
if i have a site www.hello.com/profile
instead of using GET www.hello.com/profile?is=342342?photos
how to handle it as www.hello.com/profile/342342/photos
i have controllers that handle the index and i know how to create different functions .. im stuck with www.hello.com/profile/xxxxxxxx/photos that part
In your module/[Module Name]/config/module.config.php, you can set the routes.
'router' => array(
'routes' => array(
'album' => array(
'type' => 'segment',
'options' => array(
'route' => '/album[/:action][/:id]',
'constraints' => array(
'action' => '[a-zA-Z][a-zA-Z0-9_-]*',
'id' => '[0-9]+',
),
'defaults' => array(
'controller' => 'Album\Controller\Album',
'action' => 'index',
),
),
),
),
),
Something like
'route' => '/profile/[/:id]/photos',
Reference http://framework.zend.com/manual/2.0/en/user-guide/routing-and-controllers.html
Related
Why is Zend 2 such a !##(#(!##??
OK, so I'm trying to get a simple redirect working. I have a controller called 'listitems' with an action called 'editlistitem'. After hours of banging on it with a hand sledge, I've finally got the form to work and the validation to work and the hydration to Doctrine to work so I can save the result.
The last step is to redirect the user to the 'showlistitem' action which includes the id trailing it. (full route sub path is 'listitem/showlistitem/2' where 2 is the id I want to see)
I have tried:
$this->redirect()->toRoute('/listitem/showlistitem/2');
$this->redirect()->toRoute('listitem/showlistitem/2');
$this->redirect()->toRoute('showlistitem/2');
$this->redirect()->toRoute('listitem/showlistitem', array('id' => 2));
$this->redirect()->toRoute('listitem-showlistitem', array('id' => 2));
None of them flippin work! (they all return route not found)
A route to the controller is in modules.config.php with a child route to the action. I can go directly to the url by typing it in manually and it works fine. How in the bleep do I get Zend to redirect the user to that route from an action?
The toRoute method provided by the The Redirect plugin needs the route name to be passed as parameter. This is its desciption :
toRoute(string $route = null, array $params = array(), array $options = array(), boolean $reuseMatchedParams = false)
Redirects to a named route, using the provided $params and $options to assembled the URL.
Given this simple route configuration example :
//module.config.php
'router' => array(
'routes' => array(
'home' => array(
'type' => 'Segment',
'options' => array(
'route' => '/',
'defaults' => array(
'controller' => 'index',
'action' => 'index',
),
),
),
'app' => array(
'type' => 'Literal',
'options' => array(
'route' => '/app',
'defaults' => array(
'controller' => 'index',
'action' => 'index',
),
),
'may_terminate' => true,
'child_routes' => array(
'default' => array(
'type' => 'Segment',
'options' => array(
'route' => '/[:controller[/:action[/:id]]]',
'constraints' => array(
'controller' => '[a-zA-Z][a-zA-Z0-9_-]*',
'action' => '[a-zA-Z][a-zA-Z0-9_-]*',
'id'=>'[0-9]+',
),
),
),
),
),
),
),
This redirection works :
return $this->redirect()->toRoute('app/default',
array('controller'=>'controller-name', 'action'=>'action-name', 'id'=>$id));
In your case, this would work :
return $this->redirect()->toRoute('app/default',
array('controller'=>'listitem', 'action'=>'showlistitem', 'id'=>2));
I need to create a router configuration in Zend Framework 2 like:
http://www.example.com/en
http://www.example.com/fr
http://www.example.com/es
Then the route of the modules like my "cms" module must match:
http://www.example.com/en/cms/test.html (english version)
http://www.example.com/fr/cms/test.html (french version)
http://www.example.com/es/cms/test.html (spanish version)
of course this link must match the english default language:
http://www.example.com/cms/test.html (english version)
I have already used the SimLocale without success because it doesn't handle the asset links as well. So I prefer to handle the language selection manually by a simple parameter for all my custom modules.
The question has been solved on #zftalk IRC today (thanks Michelangelo to contribute back based one what we explained to you...).
To solve the problem, we had to have a look at the defined routes:
'router' => array(
'routes' => array(
'language' => array(
'type' => 'Segment',
'options' => array(
'route' => '[/:lang]',
'defaults' => array(
'__NAMESPACE__' => 'Cms\Controller',
'controller' => 'Index',
'action' => 'page',
'lang' => 'en',
'slug' => 'homepage'
),
'constraints' => array(
'lang' => '[a-z]{2}'
)
),
'may_terminate' => true,
'child_routes' => array(
'list' => array(
'type' => 'Segment',
'options' => array(
'route' => '/cms',
'defaults' => array(
'__NAMESPACE__' => 'Cms\Controller',
'controller' => 'Index',
'action' => 'index',
'page' => 1
),
),
),
'page' => array(
'type' => 'Segment',
'options' => array(
'route' => '[/:slug].html',
'constraints' => array(
'slug' => '[a-zA-Z][a-zA-Z0-9_-]*',
),
'defaults' => array(
'action' => 'page',
),
),
),
'search' => array(
'type' => 'Segment',
'options' => array(
'route' => '/search/[query/:query]',
'constraints' => array(
'query' => '[a-zA-Z][a-zA-Z0-9_-]*',
),
'defaults' => array(
'action' => 'search',
'query' => null,
),
),
),
'paginator' => array(
'type' => 'Segment',
'options' => array(
'route' => '/list/[page/:page]',
'constraints' => array(
'page' => '[0-9]*',
),
'defaults' => array(
'page' => 1,
),
),
),
),
),
Then, the updated description of the problem was the following:
mikunos: http://www.example.com/en (homepage) this is ok
mikunos: http://www.example.com/en/cms (cms list) this is ok
mikunos: http://www.example.com/en/cms/about.html (page) this not
Which have led us on changing the 'page' route as a child route of 'list' (/cms).
Then the discussion finished with indications on what to do to setup the default language if none have been selected:
mikunos: as you have seen I need two main routes
mikunos: the first one is /lang/module and the second one is /module
mikunos: so I have to create two branches
mikunos: right?
tdutrion: you may want to use an url rewriting or something here
tdutrion: I would go for a redirect 301 from /module to /en/module so you have no duplicate content
tdutrion: and then no route can be accessed without a language
mikunos: ok
tdutrion: you can do it different ways, but I think the best one would be creating a event listener and do that before routing
tdutrion: you can also do it in your .htaccess of you are using apache, but then what if you migrate to IIS or Ngnix or else...
mikunos: interesting
tdutrion: again I believe Jurian Sluiman’s code does that
You can use subdomains for each language you need witch I suppose you don't want or you really don't need (eg. /en) to change the language of your application and/or web site. Is mandatory to use /en, /fr, etc.?
After searching a long time with no success.
before I give up, I would like to ask:
Is there a way to route a subdomain to a module in Zend Framework 2? like:
Subdomain => Module
api.site.com => api
dev.site.com => dev
admin.site.com => admin
site.com => public
...
I tried doing it like this but I can't get access to controllers other than the default (Index).
'router' => array(
'routes' => array(
'home' => array(
'type' => 'Hostname',
'options' => array(
'route' => 'site.com',
'defaults' => array(
'__NAMESPACE__' => 'Application\Controller',
'controller' => 'Index',
'action' => 'index',
),
)
)
),
),
Thank you for taking the time to help me.
Zend Framework 2 doesn't have a notion of routing to modules; all routing mappings are between a URI pattern (for HTTP routes) and a specific controller class. That said, Zend\Mvc provides an event listener (Zend\Mvc\ModuleRouteListener) which allows you to define a URI pattern that maps to multiple controllers based on a given pattern, and so emulates "module routing". To define such a route, you would place this as your routing configuration:
'router' => array(
'routes' => array(
// This defines the hostname route which forms the base
// of each "child" route
'home' => array(
'type' => 'Hostname',
'options' => array(
'route' => 'site.com',
'defaults' => array(
'__NAMESPACE__' => 'Application\Controller',
'controller' => 'Index',
'action' => 'index',
),
),
'may_terminate' => true,
'child_routes' => array(
// This Segment route captures the requested controller
// and action from the URI and, through ModuleRouteListener,
// selects the correct controller class to use
'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(
'controller' => 'Index',
'action' => 'index',
),
),
),
),
),
),
),
(Click here to see an example of this # ZendSkeletonApplication)
This is only half of the equation, though. You must also register every controller class in your module using a specific naming format. This is also done through the same configuration file:
'controllers' => array(
'invokables' => array(
'Application\Controller\Index' => 'Application\Controller\IndexController'
),
),
The array key is the alias ModuleRouteListener will use to find the right controller, and it must be in the following format:
<Namespace>\<Controller>\<Action>
The value assigned to this array key is the fully-qualified name of the controller class.
(Click here to see an example of this # ZendSkeletonApplication)
NOTE: IF you aren't using ZendSkeletonApplication, or have removed it's default Application module, you will need to register the ModuleRouteListener in one of your own modules. Click here to see an example of how ZendSkeletonApplication registers this listener
If i understand slide #39 of DASPRIDS Rounter Presentation correctly, it's as simple as - on a per module basis - to define your subdomain hosts, i.e.:
'router' => array(
'routes' => array(
'home' => array(
'type' => 'Hostname',
'options' => array(
'route' => 'api.site.com',
'defaults' => array(
'__NAMESPACE__' => 'Api\Controller',
'controller' => 'Index',
'action' => 'index',
),
)
)
),
),
Etc, you'd do this for every Module on its own.
How to allow all sub actions inside that controller with one router rule? For example this follow:
visit: site/login - works only
site/login/forgetpassword - does not work
site/login/remmeberme - does not work
Example:
$router = $e->getApplication()->getServiceManager()->get('router');
$route = Http\Literal::factory(array(
'route' => '/login',
'defaults' => array(
'controller' => 'Application\Controller\Login',
'action' => 'index'
),
));
$router->addRoute('login', $route, null);
Follow up:
How can i make it so that /login and /login/anything works?
$route = Http\Segment::factory(array(
'route' => '/login[/:action]',
'defaults' => array(
'controller' => 'Application\Controller\Login',
'action' => 'index'
),
));
$router->addRoute('login', $route, null);
There is an excellent QuickStart Tutorial available within the official Documentation. Set up your route like the following to be allowed multiple actions and an ID Parameter. Fur further information please take a look at the documentation.
You may also be interested in DASPRiDs presentation from ZendCon2012
'router' => array(
'routes' => array(
'album' => array(
'type' => 'segment',
'options' => array(
'route' => '/album[/:action][/:id]',
'constraints' => array(
'action' => '[a-zA-Z][a-zA-Z0-9_-]*',
'id' => '[0-9]+',
),
'defaults' => array(
'controller' => 'Album\Controller\Album',
'action' => 'index',
),
),
),
),
),
Build navigation from config:
'navigation' => array(
'default' => array(
'admin' => array(
'label' => 'Administration',
'controller' => 'index',
'action' => 'index',
'route' => 'admin/default',
),
'album' => array(
'label' => 'Album',
'controller' => 'index',
'action' => 'index',
'route' => 'album/default',
),
/* ... */
Routing is configured like it is true. Navigation in the menu works. Links menu lead to the desired controller/action of the desired module. But while introducing menu and a transition to one or another menuitem, active marked both points simultaneously and 'Administration' and 'Album'. As I understand it, for the reason that match the names of controllers and actions with them, but there's still the 'route' and it's different... not for nothing that the generated different url for each item... but somehow, despite this, they both are marked as active.
Routing config:
'router' => array(
'routes' => array(
'admin' => array(
'type' => 'Literal',
'options' => array(
'route' => '/admin',
'defaults' => array(
'__NAMESPACE__' => 'Admin\Controller',
'controller' => 'Index',
'action' => 'index',
),
),
'may_terminate' => true,
'child_routes' => array(
'default' => array(
'type' => 'Segment',
'options' => array(
'route' => '/[:controller][/:action[/id:id]]',
'constraints' => array(
'controller' => '[a-zA-Z][a-zA-Z0-9_-]*',
'action' => '[a-zA-Z][a-zA-Z0-9_-]*',
'id' => '[0-9]+',
),
'defaults' => array(
),
),
),
Album routing config similar...
Why this is happening? Thanks.
Looks like it's how ZF2 works (read isActive() function in Zend\Navigation\Page\Mvc.php). Initially it checks matching of route/controller/action, but if it fails, ZF2 again check for just controller/action pair. So there are three possible ways:
Open a ticket at https://github.com/zendframework/zf2/issues and wait for response.
Override \Zend\Navigation\Page\Mvc.
Choose different names for controllers (and don't use index name because it's default name for controller in Mvc.php).
If you make your controller names include the the namespace then they will be unique and won't clash:
Admin\Controller\IndexController
Album\Controller\IndexController
Rather than
Index
Index