how to do pretty url in zend framework? - php

i am wondering how can i do pretty urls with zend framework?
some background:
my url right now is: www.website.com/profile/43
the database structure is:
id userid name
1 43 John
.. ... ...
and my router is:
$router->addRoute('getUserid',
new Zend_Controller_Router_Route(
'/profile/:id',
array(
'module' => 'profile',
'controller' => 'social',
'action' => 'index'
)
)
);
obviously i would like the url to be: www.website.com/profile/John
from what research i mane it looks like i can do a lot of things with the router, add regexp, etc, but nothing on how to replace the id like in my case.
I need to do a query to find out the name and i was thinking to do it in the predispatch and use the result as a default variable, but i don't know the id since the $front->getRequest()->getParams() is not available :
$name = // do query to find out the name;
$router->addRoute('getUserid',
new Zend_Controller_Router_Route(
'/profile/:id',
array(
'id' => $name,
'module' => 'profile',
'controller' => 'social',
'action' => 'index'
)
)
);
maybe im going at this from the wrong point. Any ideas?
thanks.

It's more general than ZF specific question.
What you can do here to make the URL nice AND save your URL with high rankings is implemented in WordPress and called slugs. Slug is just the post title (just spaces replaced by hyphen and etc). But obviously there may be two posts with the same title (and, automatically, slug). So if the slug for the new post already exists it is appended by number '1' at the end. If it also exists, it is appended by '2' and repeats till it gets something unique. Obviously, you need to add a column in the table for the slug.
So in your case the first user with name John has the url www.website.com/profile/John. The next user with the name John has the url www.website.com/profile/John1 and so on.

Related

Is it possible to dynamically change view name or create a view that does not exist yet in phalcon?

I would like to know how can i do this in phalcon. I have a web site build with phalcon. All is working great now i stumbled upon a problem, here is what i need.
When a user clicks on a post that was created by another user. It takes him to this post with pictures and all things he entered to DB. I would like that in browser the name of this view is not like www.website.com/posts/index but that it is like www.website.com/posts/Nameofthepost, and like that for each other postings on the website. So that all posts (really ads) show their name up in browser. I hope i wrote everything understandable.
Appreciate all suggestions
That has to do with routing doesn't it? I modified this from my own code, I used grouping, you don't have to. I didn't test this code.
// routes.php
$router = new \Phalcon\Mvc\Router();
$router->setDefaultModule("__YOUR_MODULE__");
$router->removeExtraSlashes(true);
... your other routes ...
// posts group
$posts = new \Phalcon\Mvc\Router\Group(array(
'module' => '__YOUR_MODULE__',
'controller' => 'posts',
'action' => 'index'
));
// All the routes start with /post
$posts->setPrefix('/post');
$posts->add('/{postName}/:params', array(
'action' => 'index',
'params' => 2
));
// Maybe this will be enough for your needs,
// the one above has a catch all params, which
// has to be manually parsed
$posts->add('/{postName}', array(
'action' => 'index',
));
$posts->add('[/]*', array(
'action' => 'index',
));
$router->mount($posts);
unset($posts);
... other routes ...
return $router;
On your controller, you can get the postName param this way:
$this->dispatcher->getParam('permaPath');
As shown in the phalcon routing documentation, you can use regex in your routing config, something like this?
$posts->add('/{postName:[-0-6_A-Za-z]+}/:params', array(
'action' => 'index',
'params' => 2
));
So, only -_, 0-9, A-Z, a-z allowed for postName. If the URL had a comma in there or something, then route doesn't match, 404 page not found.

Zend Regex Router does not match anything

I currently have a Zend Framework route defined as such:
$route = new Zend_Controller_Router_Route('brand/:brand_name/series/:page',
array('controller' => 'brand',
'action' => 'series',
'page'=>'1'));
$router->addRoute('Brand Series', $route);
I'm trying to adapt this route so that the page parameter only catches numbers, so that I can add another route that uses words in the same place without the two conflicting, something like:
brand/:brand_name/series/:series_name/:page
I figured I would step along with the examples in the ZF documentation here. The very first step would be to change the route to something like this:
$route = new Zend_Controller_Router_Route_Regex('brand/:brand_name/series/(\d+)',
array('controller' => 'brand',
'action' => 'series'));
However, this small change causes routes that matched perfectly before, like /brand/johnnycupcakes/series/2 to fail, telling me Action "johnnycupcakes" does not exist and was not trapped in __call(). And in the stack trace I see:
'controller' => 'brand',
'action' => 'johnnycupcakes',
'series' => '2',
'module' => 'default'
In fact, even if I leave the route and default parameters exactly the same as in the first example, and simply change the class to Router_Route_Regex, I get the same error.
I know that the error isn't a routing conflict, because I haven't added the route that would have conflicted. Plus, it appears that it's attempting to match to the standard route. I'm testing this on version 1.11, so my version should be perfectly compatible with the code in the example.
As far as I can tell, the regex route is simply not matching, despite that it very clearly fits. Why could this possibly be failing?
EDIT:
I omitted the addRoute from the question the first time. I always had it in the code, that's not the issue.
What you need is to name a captured numeric parameter by adding third argument to Zend_Controller_Router_Route_Regex:
$route = new Zend_Controller_Router_Route_Regex(
'brand/:brand_name/series/(\d+)',
array(
'controller' => 'brand',
'action' => 'series'
),
array(
1 => 'series', // name the parameter captured by (\d+)
)
);
The second array may have keys and values in opposite relation 'series' => 1 and it will still work. Check more in ZF manual on regex routes

Changing the routes for named parameters in CakePHP

I have the following two routes which make the url /posts/recent show page 1 of the recent filter on index method of my posts controller and also allow paging like: /posts/recent/page:2 by using the * on the next route. As you can see I call page 1 on the first route so that I don't get duplicate urls for page 1.
Router::connect('/posts/recent', array('controller'=>'posts','action'=>'index','filter'=>'recent', 'page' => 1), array('pass'=>array('filter')));
Router::connect('/posts/recent/*', array(
'controller' => 'posts', 'action' => 'index', 'filter'=>'recent'), array(
'named' =>array('page' => '[\d]+'),
'pass'=>array('filter')
)
);
However I would like to make it so that named params do this instead:
/posts/recent/page/2 but how do I do it?
I've looked around the docs but don't seem to see anything about doing this...
Also is it possible to turn off named parameters in favour of query strings?
I'm using CakePHP 2.1 if it matters.
Perhaps with Router::connectNamed()?
http://book.cakephp.org/2.0/en/development/routing.html

Zend_Router omitting param-key

I've got a question considering Zend_Controller_Router. I'm using a a modular-structure in my application. The application is built upon Zend-Framework. The normal Routes are like this:
/modulename/actionname/
Since I always use an IndexController within my modules, it's not necessary to provide it in the url. Now I am able to append params like this:
/modulename/actionname/paramkey/paramvalue/paramkey/paramvalue
So this is normal in ZF, I guess. But in some cases I don't want to provide a paramkey within the url. For example I want a blog-title to be shown within the url. Of course this is intended for SEO:
/blog/show/id/6/this-is-the-blog-title
In this case, blog is the module, show is the action. id is a paramkey and 6 is the id of the blogpost I want to show. this-is-the-blog-title is of course the headline of the blogpost with the id 6. The problem is, that if I do use the assemble()-method of the router like this:
assemble(array('module' =>'blog',
'action' => 'show',
'id' => $row['blog_id'],
$row['blog_headline_de'] . '.html'));
the url results in:
blog/show/id/6/0/this-is-the-blog-title.html
As you can see a 0 is inserted as a key. But I want this 0 to be omitted. I tried this by using the blogtitle as key, like this:
assemble(array('module' =>'blog',
'action' => 'show',
'id' => $row['blog_id'],
$row['blog_headline_de'] . '.html' => ''));
This results in:
blog/show/id/6/this-is-the-blog-title.html/
Now the 0 is omitted, but I've got the slash at the end.
Do you have any solution to get an url without 0 as key and without an ending slash?
Regards,
Alex
You might want to use a custom route for this:
$router->addRoute(
'blogentry',
new Zend_Controller_Router_Route('blog/show/:id/:title',
array('controller' => 'index', 'module' => 'blog'
'action' => 'info'))
);
And call your assemble with the route as second parameter. See the Zend_Controller_Router_Route section of the documentation for more details (they even provide examples with assemble).
Or in a more general way:
$router->addRoute(
'generalseo',
new Zend_Controller_Router_Route(':module/:action/:id/:title',
array('controller' => 'index'))
);

Zend Framework - Optional Router Labels

Very likely I'm going about this in the wrong way entirely. I'm completely new to the framework..
The site I am developing has two "parts" that are mainly separate. An informational/community half, and a commerce half. I'm using the following directory structure:
--application
----default
------controllers
------layouts
------models
------views
----store
------controllers
------layouts
------models
------views
--config
--library
--public
I would like to have a URL structure when browsing for products as follows:
/view/category/model/revision
This would pull up a specific product/revision - but I would like to back-track as well (browsing all revisions, all models, etc). I can't figure out how to achieve this.. My route is setup like this:
Bootstrap.php
$front = Zend_Controller_Front::getInstance();
$router = $front->getRouter();
$route = new Zend_Controller_Router_Route(
'view/:cid/:sku/:rev',
array('module' => 'store', 'controller' => 'index', 'action' => 'index')
);
$router->addRoute('view', $route);
This works fine for pulling up a specific product, but throws an exception (it reverts to the default module and complains that the controller 'view' does not exist) when leaving out any of the 3 labeled parameters. Is it possible to put in optional labels, where it would continue to use the view controller under the store module for 1-3 parameters? Am I missing the point?
I found nothing in the framework docs, but I wouldn't be surprised if I just couldn't find the page.. There's something about the Zend Framework documentation that drives me crazy.
Thank You
I'm not really a ZendFramework guy, but it's obvious the missing parameters are causing the issue. Routes are matched in reverse order. Could it be passing a NULL value to the view when 3 parameters are passed and it is expecting 4?
What if you tried something like:
$route = new Zend_Controller_Router_Route(
'view/:cid/:sku/:rev',
array('module' => 'store', 'controller' => 'index', 'action' => 'index', 'cid' => 0, 'sku' => 0, 'rev' => 0)
);
It should pass default values if they are not provided.

Categories