I think you mean with categoryname as action in your route the :categoryname should be used as an action? There are two methods you can use. First is you add only the routes to the router where categories exist. When category/foo is requested the router won't recognize the route and throw the 404 error.
The second option is you catch all category/* routes and inside your action you check if the category exists.
For the first option, add a frontController plugin with a routeStartup function. In this hook you can do:
public function routeStartup(Zend_Controller_Request_Abstract $request)
{
// Get the router
$router = Zend_Controller_Front::getInstance()->getRouter();
// Fetch all your categories
$category = new Application_Model_Category;
$categories = $category->fetchAll();
// Loop and add all individual categories as routes
foreach ($categories as $category) {
$route = 'category/:' . $category->name;
$params = array(
'module' => 'default',
'controller' => 'category',
'action' => $category->name
);
$route = new Zend_Controller_Router_Route($route, $params);
$router->addRoute($category->name, $route);
}
}
The other method is more simple for the route. In your application.ini:
resources.router.routes.category.route = "category/:action"
resources.router.routes.category.module = "default"
resources.router.routes.category.controller = "category"
Now all requests from category/SOMETHING will go to the default module, category controller. The dispatcher checks if the action SOMETHING exists. When it does, it executes the action. When not, a Zend_Controller_Action_Exception ("action does not exist") is throw.
So in short, both methods work. With the first you get more control. The second is more simple but when e.g. an editAction, addAction or removeAction in the categoryController exist, they can be triggered as well (so be careful with that method).
PS. Of course, the routeStartup function should have a caching mechanism to prevent a database query on each request.