This is not a problem with the Views module; it's how Drupal behaves.
If you look at menu_get_item(), you will notice the following code.
$original_map = arg(NULL, $path);
$parts = array_slice($original_map, 0, MENU_MAX_PARTS);
$ancestors = menu_get_ancestors($parts);
$router_item = db_query_range('SELECT * FROM {menu_router} WHERE path IN (:ancestors) ORDER BY fit DESC', 0, 1, array(':ancestors' => $ancestors))->fetchAssoc();
I tried the following code, in a test site.
$original_map = arg(NULL, 'people/bob');
$parts = array_slice($original_map, 0, MENU_MAX_PARTS);
$ancestors = menu_get_ancestors($parts);
What I got is an array containing the following items:
- people/bob
- people/%
- people
In your case, as there isn't a menu callback for people/bob, and people/%, the query executed from menu_get_item()
will find the menu callback for people, the view you have defined.
To avoid people/bob returns the view page, I would create a custom module with the following code.
function mymodule_menu() {
$items['people/%'] = array(
'page callback' => 'mymodule_people_view',
'page arguments' => array(1),
'access arguments' => array('access content'),
'type' => MENU_CALLBACK,
);
}
function mymodule_people_view($username) {
$alias = "people/$username";
$path = drupal_get_normal_path($alias);
if ($alias == $path) {
// $alias is not a defined alias; in this case, drupal_get_normal_path()
// returns the string it gets as argument.
drupal_not_found();
}
else {
drupal_goto($path);
}
}
There is a module to resolve this issue (Views 404), which has now a version for Drupal 7.
Are your views returning a 200 when it should return a 404? Views404 is the answer! This is very helpful for any caching layer and it will help SEO.
[...]
Standard Drupal behavior is to pass all arguments through, whether or not they requested. Sometimes this behavior is desired. The views 404 module assumes that by default you do not want arguments passed through. 404s for views can also be accomplished by setting the Global: Null under Arguments.