How can I simply serve static pages with child routes in ZF2? - php

Maybe I am overcomplicating this, but the documentation isn't very clear to me. I am using Zend Framework 2 to serve some dynamic content, but I also have a few routes that are purely static HTML pages. Those static pages are all children of a parent route. For example:
/foo/bar
/foo/baz
/foo/cat
How can I just simply serve up these static pages if I already have a "FooController" I should add that /foo doesn't have a view itself, but all of the foo children do.

The easiest would be to set up your route like this:
'foopage' => array(
'type' => 'Zend\Mvc\Router\Http\Segment',
'options' => array(
'route' => '/foo/:action',
'defaults' => array(
'controller' => 'My\Controller\Foo',
'action' => 'index'
),
'constraints' => array(
'action' => '[a-zA-Z]+'
)
),
)
Then inside your FooController simply create a couple of empty actions like indexAction, fooAction, barAction, bazAction and create the respective templates.
An alternative would be to use the Module of Matthew called PhlySimplePage

Related

PHP ZF2 - How to create dynamic urls

I have been tasked to explore the possibilities of creating dynamic urls.
What we try to achieve is serving a domain for the client.
eg. www.example.com/clients/john/
eg. www.example.com/clients/bill/
These urls are not fixed, but have to be made dynamically everytime a Client registers at our site. Our URL's are build of Controllers and Actions. Like www.example.com/controller/action.
How can this be achieved in the PHP Zend Framework 2?
Big thanks in advance!
All you need is the ZF2 Manual:
I suggest to use segment routes
You can define them like:
'client' => array(
'route' => '/clients/:username',
'constraints' => array(
'username' => '[a-zA-Z][a-zA-Z0-9-]+', //accepted value pattern
),
'defaults' => array( //which action to invoke
'controller' => 'Application\Controller\ClientController',
'action' => 'showclient',
),
));
Then you can create an url with url helper like:
$this->url('client', array('username' => 'John'));
And in your controller you will be able to get username param with:
$this->params()->fromRoute('username');

zend framework 2 default routing action change url to default action

i thought i had the routing under control until i found out that i have now clue of how to have the default action url change, that means:
when ever a user enters a url, for example:
http://www.mysite.com/form/myform
the routing will always redirect him to the default action "show" (one of many actions this controller has):
http://www.mysite.com/form/myform/show
but my url remains the same (with the "show" action):
http://www.mysite.com/form/myform
what am i missing here?
'routes' => array(
'form' => array(
'type' => 'segment',
'options' => array(
'route' => '/form[/:form[/:action]]',
'constraints' => array(
'form' => '[a-zA-Z][a-zA-Z0-9_-]*',
'action' => '[a-zA-Z][a-zA-Z0-9_-]*',
),
'defaults' => array(
'controller' => 'Form\Controller\Form',
'action' => 'show',
),
),
),
),
thanks!
edited note:
i have noticed (thanks to #codeHeart marks) that i had some mistakes/misclarification trying to explain the problem, so i edited the main question examples.
thanks again all!
Looking at this in your question/
http://www.mysite.com/controller
and your router configuration I expect that should be throwing a 404 error, as there is no matching route in your config that matches /controller(If there are more routes other than the one that you show in you question, let us know or maybe you mistyped this url).
Apart from above,
your route tells to do the following:-
if url is
http://yoursite/form OR
http://yoursite/form/controller
go to the controller action that you have mentioned in the defaults, as the route was matched to the url but didn't get matched completely to an action so going to the default.
A non existing controller or a non existing action should be throwing 404. e.g
http://yoursite/form/controller/non-existing-action
Even this url
http://yoursite/form/
won't get matched according to your route and will be throwing a 404.
And for your question if you want to change the default action to something other then the "show" action, simply change the action parameter/key in defaults
'defaults' => array(
'controller' => 'Form\Controller\Form',
'action' => 'some-other-action',
),
Hope this helps and sorry if I was of no help.

Unable to route with module in ZF2

I've created a module, a basic copy of the the albums example given in the ZF2 documentation, however, with the new module, I am not able to access it at all - I'm always given a 404 error. I'm building this on the ZF2 skeleton.
I've got three modules loaded: Application, Frontend and Security.
Both Frontend and Security are duplicates of each other, however, I have thoroughly checked and there is no reference to old code (as I literally copied the module folder and renamed/rewrote references).
The module is also loaded in application.config.php.
Any ideas on what I'm missing?
Module Config:
return array(
'controllers' => array(
'invokables' => array(
'Security\Controller\Security' => 'Security\Controller\SecurityController',
),
),
'router' => array(
'routes' => array(
'security' => array(
'type' => 'segment',
'options' => array(
'route' => '/security[/:action][/:id]',
'constraints' => array(
'action' => '[a-zA-Z][a-zA-Z0-9_-]*',
'id' => '[0-9]+',
),
'defaults' => array(
'controller' => 'Security\Controller\Security',
'action' => 'index',
),
),
),
),
),
'view_manager' => array(
'template_path_stack' => array(
'security' => __DIR__ . '/../view',
),
),
);
I had the same problem while following the skeleton application tutorial (Getting started: A skeleton application). Whenever I would go to the album url in the browser (ZendSkeletonApplication/public/album in my case), I would get a 404 error page but no details on why I got the 404. It wasn't clear to me how I would be able determine why I was getting the 404 when I had double checked everything and was pretty sure I copied and configured the Album module properly. It turned out that I was missing a slash in my route (module.config.php). For example I had 'route' => 'album[/:action][/:id]' instead of 'route' => '/album[/:action][/:id]'.
I was only able to figure it out by intentionally causing errors by misspelling things like making the 'Album\Controller\Albums' instead of 'Album\Controller\Album'in the invokables value, this would cause a stack trace to display which then showed the ZF2 classes that where called on the request. I would continue to misspell, test, and then correct each part of the module.config.php until I was given a clue to what part of the configuration was causing the error.
I'm pretty sure this was not the best way to debug an application's configuration.
There is few things that need to be make sure is:-
You have to add your module in
application.config.php (which you are saying you done it.)
Security\Controller\Security has to be same in default too (which you already has)
One more thing is Your folder structure....
-
Just to doulbe check you have a /MODULE/src/MODULE/Controller/CONTROLLER_FILE_NAME.php
I hope that helps..
I know it is an old post. However another thing to make sure you have in the modules top directory (same directory as the Module.php file) is the "autoload_classmap.php"
file with "<?php return array();?>" inside of it.
A simple tip to know whether your rule has already added correctly to the routes or not, you may check the routes value in the config file inside any working module, as following:
$config = $this->serviceLocator->get('config');
var_dump($config);

Routing in Zend Framework 2, skip 'index' action in url but get id

I have a controller that can be invoked as modulename/xmlcoverage with index action and some other actions, let say testAction().
The url to this controller is xml/coverage.
The default way is then that xml/coverage maps to my index action. And that xml/coverage/test maps to testAction. If I need an id for testAction, the url would be like xml/coverage/test/33 for instance.
However, for index action, it would need to be xml/coverage/index/33
Where I would like it to be xml/coverage/33.
This is my route
'xmlcoverage' => array(
'type' => 'segment',
'options' => array(
'route' => '/xml/coverage[/:action][/:id]',
'constraints' => array(
'action' => '[a-zA-Z][a-zA-Z0-9_-]*',
'id' => '[0-9]+',
),
'defaults' => array(
'controller' => 'modulename/xmlcoverage',
'action' => 'index',
),
),
),
When trying the url xml/coverage/33, I believe 33 should map to id, as it doesn't match the regex of action and both are optional. And since it doesn't match an action, the default (index) should be used.
Instead I get an error saying that the url cannot be matched by routing.
So for me, it acts as if the route was '/xml/coverage[/:action[/:id]]' because I for some reason have to specify action for it to recognize the id.
What am I doing wrong, and how can I get the urls to work as I'd like?
Thanks.
EDIT: Here is a problem.
Doing this in my view:
$this->url('xmlcoverage', array('action' => 'index', 'id' => $someid))
actually gives an URL on the form xml/coverage/1 which will crash!
Changing the route to /xml/coverage[/:action[/:id]] will at least make the url helper produce working urls..
After talking and debugging with the nice ZF2 folks on IRC, we tracked down a bug in the routing.
During the discussion I made a small example to my issue, which is here.
As you can see from the var dump here, the action gets lost in the second case where it should default to "index".
But if anyone needs this functionality to work right now, here are ways that fix it:
Instead of having the route to be /test[/:action][/:id] have it to be /test[/:action[/:id]], then the url helper will add /index/ and at least it works.
Make a new route where you only listen for /test[/:id] in addition to the other one.
In your controller, do public function notFoundAction() { $view = new ViewModel($this->indexAction()); //etc} Kinda hacky, but with this bug it will dispatch a not found action, which you can piggyback.

Kohana 3.1 routes with default subdirectories

I have an application that is essentially working until I tried to implement an Auth module for logins and registrations.
My application directory structure is basically:
application
-- classes
-- controller
-- admin
(admin area)
-- block
(blocks to display within pages)
-- page
(default pages)
By default I want to have URL's such as http://www.testsite.com/test which would access the Controller_Page_Test class. Or to explicitly call admin or block pages http://www.testsite.com/admin/test which would access the Controller_Admin_Test class. To further complicate matters it also needs to handle optional actions and id's.
I said at the top that this is basically working correctly - until I've tried to add in the Auth module. The Auth module calls http://www.testsite.com/user/login but instead of accessing the module's path via the default, it looks in the page directory.
To overcome this I placed a higher level route but now this has become my default page handler. Explicit calls still get through.
My routes currently look like this:
Route::set('user', '(<controller>(/<action>(/<id>)))', array('controller' => 'user|admin_user'))
->defaults(array(
'controller' => 'user',
'action' => 'index',
'id' => NULL,
));
Route::set('with_dir', '<directory>/<controller>(/<action>(/<id>))', array('directory' => 'block|admin'))
->defaults(array(
'directory' => 'page',
'controller' => 'home',
'action' => 'index',
));
Route::set('just_id', '<controller>(/<id>)', array('id' => '\d+'))
->defaults(array(
'directory' => 'page',
'controller' => 'home',
'action' => 'index',
));
Route::set('auto_dir', '<controller>(/<action>(/<id>))', array('id' => '\d+'))
->defaults(array(
'directory' => 'page',
'controller' => 'home',
'action' => 'index',
));
Route::set('default', '(<controller>(/<action>(/<id>)))')
->defaults(array(
'controller' => 'prototype',
'action' => 'index',
));
Can this be cleaned up any better? And how do I get this module to only kick in when I need it to?
Yes, it can be cleaned better. Kohana developers encourage people using this framework to add as much routes as needed. You can even specify them for each action which will enable you to change URLs in the future (eg. instead of /user/login you may wish to have /signin), if you use proper methods to generate links etc. (eg. Route::url() helper).
Now, saying that, here is the other way to specify the user route:
Route::set('user', '<controller>(/<action>(/<id>))', array('controller' => '(user|admin_user)'))
->defaults(array(
'controller' => 'user',
'action' => 'index',
));
Which will match only the requests, where the first part of the URI is given and is equal either to user or admin_user. Previously the controller part was optional, thus was also matching calls to / URI.

Categories